//------------------------------------------------------- //experiment internal void LoadOpenFontLayoutInfo(GDEF gdefTable, GSUB gsubTable, GPOS gposTable, BASE baseTable, COLR colrTable, CPAL cpalTable) { //*** this.GDEFTable = gdefTable; this.GSUBTable = gsubTable; this.GPOSTable = gposTable; this.BaseTable = baseTable; this.COLRTable = colrTable; this.CPALTable = cpalTable; //--------------------------- //1. fill glyph definition if (gdefTable != null) { gdefTable.FillGlyphData(this.Glyphs); //if (this.Glyphs != null) //{ //} //else if (_cffTable != null) //{ // //post script outline // //TODO: fill gdef for cff font //} } }
internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input) { var rd = new EntriesReaderHelper(tables, input); NameEntry nameEntry = rd.Read(new NameEntry()); OS2Table os2Table = rd.Read(new OS2Table()); //for preview, read ONLY script list from gsub and gpos (set OnlyScriptList). Meta metaTable = rd.Read(new Meta()); GSUB gsub = rd.Read(new GSUB() { OnlyScriptList = true }); GPOS gpos = rd.Read(new GPOS() { OnlyScriptList = true }); Cmap cmap = rd.Read(new Cmap()); //gsub and gpos contains actual script_list that are in the typeface Languages langs = new Languages(); langs.Update(os2Table, metaTable, cmap, gsub, gpos); return(new PreviewFontInfo( nameEntry, os2Table, langs)); }
//------------------------------------------------------- //experiment internal void LoadOpenFontLayoutInfo(GDEF gdefTable, GSUB gsubTable, GPOS gposTable, BASE baseTable) { //*** this.GDEFTable = gdefTable; this.GSUBTable = gsubTable; this.GPOSTable = gposTable; this.BaseTable = baseTable; //--------------------------- //1. fill glyph definition if (gdefTable != null) { gdefTable.FillGlyphData(this.Glyphs); } }
internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input) { var rd = new EntriesReaderHelper(tables, input); NameEntry nameEntry = rd.Read(new NameEntry()); OS2Table os2Table = rd.Read(new OS2Table()); //for preview, read ONLY script list from gsub and gpos (set OnlyScriptList). Meta metaTable = rd.Read(new Meta()); GSUB gsub = rd.Read(new GSUB() { OnlyScriptList = true }); GPOS gpos = rd.Read(new GPOS() { OnlyScriptList = true }); //gsub and gpos contains actual script_list that are in the typeface Languages langs = new Languages(); langs.Update(os2Table, metaTable, gsub, gpos); return(new PreviewFontInfo( nameEntry.FontName, nameEntry.FontSubFamily, nameEntry.TypographicFamilyName, nameEntry.TypographyicSubfamilyName, os2Table.usWeightClass, langs, Extensions.TypefaceExtensions.TranslatedOS2FontStyle(os2Table)) { PostScriptName = nameEntry.PostScriptName, UniqueFontIden = nameEntry.UniqueFontIden, VersionString = nameEntry.VersionString }); }
internal Typeface ReadTableEntryCollection(TableEntryCollection tables, BinaryReader input) { OS2Table os2Table = ReadTableIfExists(tables, input, new OS2Table()); NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry()); Head header = ReadTableIfExists(tables, input, new Head()); MaxProfile maximumProfile = ReadTableIfExists(tables, input, new MaxProfile()); HorizontalHeader horizontalHeader = ReadTableIfExists(tables, input, new HorizontalHeader()); HorizontalMetrics horizontalMetrics = ReadTableIfExists(tables, input, new HorizontalMetrics(horizontalHeader.HorizontalMetricsCount, maximumProfile.GlyphCount)); //--- PostTable postTable = ReadTableIfExists(tables, input, new PostTable()); CFFTable ccf = ReadTableIfExists(tables, input, new CFFTable()); //-------------- Cmap cmaps = ReadTableIfExists(tables, input, new Cmap()); GlyphLocations glyphLocations = ReadTableIfExists(tables, input, new GlyphLocations(maximumProfile.GlyphCount, header.WideGlyphLocations)); Glyf glyf = ReadTableIfExists(tables, input, new Glyf(glyphLocations)); //-------------- Gasp gaspTable = ReadTableIfExists(tables, input, new Gasp()); VerticalDeviceMetrics vdmx = ReadTableIfExists(tables, input, new VerticalDeviceMetrics()); //-------------- Kern kern = ReadTableIfExists(tables, input, new Kern()); //-------------- //advanced typography GDEF gdef = ReadTableIfExists(tables, input, new GDEF()); GSUB gsub = ReadTableIfExists(tables, input, new GSUB()); GPOS gpos = ReadTableIfExists(tables, input, new GPOS()); BASE baseTable = ReadTableIfExists(tables, input, new BASE()); COLR colr = ReadTableIfExists(tables, input, new COLR()); CPAL cpal = ReadTableIfExists(tables, input, new CPAL()); VerticalHeader vhea = ReadTableIfExists(tables, input, new VerticalHeader()); if (vhea != null) { VerticalMetrics vmtx = ReadTableIfExists(tables, input, new VerticalMetrics(vhea.NumOfLongVerMetrics)); } //test math table MathTable mathtable = ReadTableIfExists(tables, input, new MathTable()); EBLCTable fontBmpTable = ReadTableIfExists(tables, input, new EBLCTable()); //--------------------------------------------- //about truetype instruction init //--------------------------------------------- Typeface typeface = null; bool isPostScriptOutline = false; if (glyf == null) { //check if this is cff table ? if (ccf == null) { //TODO: review here throw new NotSupportedException(); } //... //PostScript outline font isPostScriptOutline = true; typeface = new Typeface( nameEntry, header.Bounds, header.UnitsPerEm, ccf, horizontalMetrics, os2Table); } else { typeface = new Typeface( nameEntry, header.Bounds, header.UnitsPerEm, glyf.Glyphs, horizontalMetrics, os2Table); } //---------------------------- typeface.CmapTable = cmaps; typeface.KernTable = kern; typeface.GaspTable = gaspTable; typeface.MaxProfile = maximumProfile; typeface.HheaTable = horizontalHeader; //---------------------------- if (!isPostScriptOutline) { FpgmTable fpgmTable = ReadTableIfExists(tables, input, new FpgmTable()); //control values table CvtTable cvtTable = ReadTableIfExists(tables, input, new CvtTable()); if (cvtTable != null) { typeface.ControlValues = cvtTable._controlValues; } if (fpgmTable != null) { typeface.FpgmProgramBuffer = fpgmTable._programBuffer; } PrepTable propProgramTable = ReadTableIfExists(tables, input, new PrepTable()); if (propProgramTable != null) { typeface.PrepProgramBuffer = propProgramTable._programBuffer; } } //------------------------- typeface.LoadOpenFontLayoutInfo( gdef, gsub, gpos, baseTable, colr, cpal); //------------ //test { SvgTable svgTable = ReadTableIfExists(tables, input, new SvgTable()); if (svgTable != null) { typeface._svgTable = svgTable; } } typeface.PostTable = postTable; if (mathtable != null) { var mathGlyphLoader = new MathGlyphLoader(); mathGlyphLoader.LoadMathGlyph(typeface, mathtable); } #if DEBUG //test //int found = typeface.GetGlyphIndexByName("Uacute"); if (typeface.IsCffFont) { //optional typeface.UpdateAllCffGlyphBounds(); } #endif return(typeface); }
public TtfTypeface Read(Stream stream, ReadFlags readFlags = ReadFlags.Full) { var little = BitConverter.IsLittleEndian; using (var input = new ByteOrderSwappingBinaryReader(stream)) { ushort majorVersion = input.ReadUInt16(); ushort minorVersion = input.ReadUInt16(); ushort tableCount = input.ReadUInt16(); ushort searchRange = input.ReadUInt16(); ushort entrySelector = input.ReadUInt16(); ushort rangeShift = input.ReadUInt16(); var tables = new TableEntryCollection(); for (int i = 0; i < tableCount; i++) { tables.AddEntry(new UnreadTableEntry(ReadTableHeader(input))); } //------------------------------------------------------------------ OS2Table os2Table = ReadTableIfExists(tables, input, new OS2Table()); NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry()); Head header = ReadTableIfExists(tables, input, new Head()); MaxProfile maximumProfile = ReadTableIfExists(tables, input, new MaxProfile()); HorizontalHeader horizontalHeader = ReadTableIfExists(tables, input, new HorizontalHeader()); HorizontalMetrics horizontalMetrics = ReadTableIfExists(tables, input, new HorizontalMetrics(horizontalHeader.HorizontalMetricsCount, maximumProfile.GlyphCount)); //-------------- Cmap cmaps = ReadTableIfExists(tables, input, new Cmap()); GlyphLocations glyphLocations = ReadTableIfExists(tables, input, new GlyphLocations(maximumProfile.GlyphCount, header.WideGlyphLocations)); Glyf glyf = ReadTableIfExists(tables, input, new Glyf(glyphLocations)); //-------------- Gasp gaspTable = ReadTableIfExists(tables, input, new Gasp()); VerticalDeviceMetrics vdmx = ReadTableIfExists(tables, input, new VerticalDeviceMetrics()); //-------------- PostTable postTable = ReadTableIfExists(tables, input, new PostTable()); Kern kern = ReadTableIfExists(tables, input, new Kern()); //-------------- //advanced typography GDEF gdef = ReadTableIfExists(tables, input, new GDEF()); GSUB gsub = ReadTableIfExists(tables, input, new GSUB()); GPOS gpos = ReadTableIfExists(tables, input, new GPOS()); BASE baseTable = ReadTableIfExists(tables, input, new BASE()); COLR colr = ReadTableIfExists(tables, input, new COLR()); CPAL cpal = ReadTableIfExists(tables, input, new CPAL()); VerticalHeader vhea = ReadTableIfExists(tables, input, new VerticalHeader()); if (vhea != null) { VerticalMatric vmtx = ReadTableIfExists(tables, input, new VerticalMatric(vhea.NumOfLongVerMetrics)); } EBLCTable fontBmpTable = ReadTableIfExists(tables, input, new EBLCTable()); //--------------------------------------------- //about truetype instruction init //--------------------------------------------- var typeface = new TtfTypeface( nameEntry, header.Bounds, header.UnitsPerEm, glyf.Glyphs, horizontalMetrics, os2Table); //---------------------------- typeface.CmapTable = cmaps; typeface.KernTable = kern; typeface.GaspTable = gaspTable; typeface.MaxProfile = maximumProfile; typeface.HheaTable = horizontalHeader; //---------------------------- FpgmTable fpgmTable = ReadTableIfExists(tables, input, new FpgmTable()); //control values table CvtTable cvtTable = ReadTableIfExists(tables, input, new CvtTable()); if (cvtTable != null) { typeface.ControlValues = cvtTable.controlValues; } if (fpgmTable != null) { typeface.FpgmProgramBuffer = fpgmTable.programBuffer; } PrepTable propProgramTable = ReadTableIfExists(tables, input, new PrepTable()); if (propProgramTable != null) { typeface.PrepProgramBuffer = propProgramTable.programBuffer; } //------------------------- typeface.LoadOpenFontLayoutInfo( gdef, gsub, gpos, baseTable, colr, cpal); return(typeface); } }
protected static FR_L6BH_MBHR_1624 Execute(DbConnection Connection, DbTransaction Transaction, P_L6BH_MBHR_1624 Parameter, CSV2Core.SessionSecurity.SessionSecurityTicket securityTicket = null) { #region UserCode var returnValue = new FR_L6BH_MBHR_1624(); returnValue.Result = new L6BH_MBHR_1624(); returnValue.Result.areThereTreatmentsOrFollowupsBilledForParameters = false; List <TreatmentData> AllSortedTreatments = new List <TreatmentData>(); List <Guid> listOfPractices = new List <Guid>(); //treatments and followups for selected month and your (only treatment table) var allTreatmentsForTimeRange = cls_Get_Treatments_and_Followups_for_SelectedMonth_and_Year.Invoke(Connection, Transaction, new P_L5TR_GTaFfSMaY_1619() { SelectedMounth = Parameter.SelectedMounth, SelectedYear = Parameter.SelectedYear }, securityTicket).Result.ToList(); if (allTreatmentsForTimeRange.Count > 0) { returnValue.Result.areThereTreatmentsOrFollowupsBilledForParameters = true; } else { return(returnValue); } List <Guid> listOfTreatmentIDs = allTreatmentsForTimeRange.Select(i => i.HEC_Patient_TreatmentID).ToList(); //all treatments and followupss that have bill position table (for selected month, year) var treatmentData = cls_Get_BilledTreatmentData_for_Report.Invoke(Connection, Transaction, new P_L5BH_GBTDfR_1158() { TreatmentID = listOfTreatmentIDs.ToArray() }, securityTicket).Result.ToList(); //get all practices listOfPractices = treatmentData.Select(i => i.TreatmentPractice_RefID).Distinct().ToList(); //from this list remove all treatments/followups that do not have bill positions .... // what is left is old followups which do not have sepparate bill position foreach (var item in treatmentData) { var treatmentToRemove = allTreatmentsForTimeRange.Where(i => i.HEC_Patient_TreatmentID == item.HEC_Patient_TreatmentID).FirstOrDefault(); if (treatmentToRemove != null) { allTreatmentsForTimeRange.Remove(treatmentToRemove); } } var oldFollowups = allTreatmentsForTimeRange; #region Get all followups with their own bill position and organise them || FOLLOWUP DATA var followupsWihtOwnBillPosition = treatmentData.Where(i => i.External_PositionType == "Nachsorge").ToList(); List <TreatmentData> followupsWihtOwnBillPositionSorted = new List <TreatmentData>(); foreach (var item in followupsWihtOwnBillPosition) { TreatmentData followupData = new TreatmentData(); followupData.Date = item.TreatmentDate.ToString("dd.MM.yyyy", new CultureInfo("de-DE")); followupData.FirstName = item.FirstName; followupData.LastName = item.LastName; followupData.Birthday = item.BirthDate.ToString("dd.MM.yyyy", new CultureInfo("de-DE")); followupData.Article = item.Products[0].Product_Name.Contents[0].Content;; followupData.Vorgassnumber = item.VorgangsNumber; followupData.PracticeID = item.TreatmentPractice_RefID; List <GPOS> GPOS = new List <GPOS>(); GPOS gposData = new GPOS(); gposData.Number = item.GPOS; gposData.Text = "Nachsorgebehandlung"; gposData.Price = double.Parse(item.PositionValue_IncludingTax); GPOS.Add(gposData); followupData.GPOS = GPOS; if (item.TCode == "3") { followupData.isAOKConfirmedStatus = true; } else { followupData.isAOKConfirmedStatus = false; } followupsWihtOwnBillPositionSorted.Add(followupData); } #endregion //from all bill positions remove followups foreach (var item in followupsWihtOwnBillPosition) { treatmentData.Remove(item); } List <Guid> OLDFollowupsThatHaveTreatmentInDifferentPractice = new List <Guid>(); foreach (var item in oldFollowups) { if (treatmentData.Where(i => i.HEC_Patient_TreatmentID == item.IfTreatmentFollowup_FromTreatment_RefID).ToList().Count == 0) { OLDFollowupsThatHaveTreatmentInDifferentPractice.Add(item.HEC_Patient_TreatmentID); } } #region Organise Treatment data List <TreatmentData> TreatmentsSorted = new List <TreatmentData>(); List <Guid> Treatments = treatmentData.Select(i => i.HEC_Patient_TreatmentID).Distinct().ToList(); foreach (var treatmentID in Treatments) { var treatment = treatmentData.Where(i => i.HEC_Patient_TreatmentID == treatmentID && (i.External_PositionType == "Behandlung | Nachsorge" || i.External_PositionType == "Behandlung")).FirstOrDefault(); TreatmentData treatmentSorted = new TreatmentData(); treatmentSorted.Date = treatment.TreatmentDate.ToString("dd.MM.yyyy", new CultureInfo("de-DE")); treatmentSorted.PracticeID = treatment.TreatmentPractice_RefID; treatmentSorted.FirstName = treatment.FirstName; treatmentSorted.LastName = treatment.LastName; treatmentSorted.Birthday = treatment.BirthDate.ToString("dd.MM.yyyy", new CultureInfo("de-DE")); treatmentSorted.Vorgassnumber = treatment.VorgangsNumber; if (treatment.Products != null && treatment.Products.Length > 0) { treatmentSorted.Article = treatment.Products[0].Product_Name.Contents[0].Content; } else { treatmentSorted.Article = ""; } if (treatment.TCode == "3") { treatmentSorted.isAOKConfirmedStatus = true; } else { treatmentSorted.isAOKConfirmedStatus = false; } List <GPOS> GPOS = new List <GPOS>(); GPOS gposData = new GPOS(); gposData.Number = treatment.GPOS; gposData.Text = "Erstbehandlung " + treatmentSorted.Article; gposData.Price = 230; gposData.ID = 1; GPOS.Add(gposData); if (treatment.External_PositionType == "Behandlung | Nachsorge") { gposData = new GPOS(); gposData.Number = treatment.GPOS; gposData.Text = "Nachsorgebehandlung"; if (treatmentSorted.Article != "Ozurdex") { gposData.Price = 60; } else { gposData.Price = 150; } gposData.ID = 2; GPOS.Add(gposData); } gposData = new GPOS(); gposData.Number = String.Empty; gposData.Text = "Management Pauschaule"; gposData.Price = 0; gposData.ID = 5; GPOS.Add(gposData); if (treatmentSorted.Article.ToLower().Contains("bevacizumab")) { var BevacuzimabTreatment = treatmentData.Where(i => i.HEC_Patient_TreatmentID == treatmentID && ((i.External_PositionType == "Zusatzposition Bevacuzimab") || i.External_PositionType == "Zusatzposition Bevacizumab")).FirstOrDefault(); if (BevacuzimabTreatment != null) { gposData = new GPOS(); gposData.Number = BevacuzimabTreatment.GPOS; gposData.Text = "Medikamentenkosten Bevacizumab"; gposData.Price = double.Parse(BevacuzimabTreatment.PositionValue_IncludingTax); gposData.ID = 3; GPOS.Add(gposData); } } var WartezeitenmanagementData = treatmentData.Where(i => i.HEC_Patient_TreatmentID == treatmentID && (i.External_PositionType == "Wartezeitenmanagement")).FirstOrDefault(); if (WartezeitenmanagementData != null) { gposData = new GPOS(); gposData.Number = WartezeitenmanagementData.GPOS; gposData.Text = "Wartezeitenmanagement"; gposData.Price = double.Parse(WartezeitenmanagementData.PositionValue_IncludingTax); gposData.ID = 4; GPOS.Add(gposData); } GPOS = GPOS.OrderBy(i => i.ID).ToList(); treatmentSorted.GPOS = GPOS; TreatmentsSorted.Add(treatmentSorted); } #endregion #region Combine Treatment bill positions with followup bill positions foreach (var item in followupsWihtOwnBillPositionSorted) { var treatment = TreatmentsSorted.Where(i => i.Date == item.Date && i.FirstName == item.FirstName && i.LastName == item.LastName && i.Birthday == item.Birthday).FirstOrDefault(); if (treatment == null) { TreatmentsSorted.Add(item); } else { GPOS gposData = new GPOS(); gposData.Number = treatment.GPOS.Where(i => i.ID == 1).First().Number; gposData.Text = "Nachsorgebehandlung"; if (treatment.Article != "Ozurdex") { gposData.Price = 60; } else { gposData.Price = 150; } gposData.ID = 2; treatment.GPOS.Add(gposData); treatment.GPOS = treatment.GPOS.OrderBy(i => i.ID).ToList(); } } #endregion #region Organise OLD Followups (followups that do not have sepparate bill position) and add them to all Treatments if (OLDFollowupsThatHaveTreatmentInDifferentPractice.Count > 0) { var rawDataForOldFollowups = cls_Get_BilledFollowupData_for_Report.Invoke(Connection, Transaction, new P_L5BH_GBFDfR_1443() { FollowUpID = OLDFollowupsThatHaveTreatmentInDifferentPractice.ToArray() }, securityTicket).Result.ToList(); rawDataForOldFollowups = rawDataForOldFollowups.Where(i => i.External_PositionType == "Behandlung | Nachsorge" || i.External_PositionType == "Behandlung").ToList(); List <TreatmentData> OldFollowupsSorted = new List <TreatmentData>(); foreach (var item in rawDataForOldFollowups) { TreatmentData followup = new TreatmentData(); followup.Date = item.FollowupDate.ToString("dd.MM.yyyy", new CultureInfo("de-DE")); followup.PracticeID = item.FollowupPracticeID; followup.FirstName = item.FirstName; followup.LastName = item.LastName; followup.Birthday = item.BirthDate.ToString("dd.MM.yyyy", new CultureInfo("de-DE")); followup.Vorgassnumber = item.VorgangsNumber; if (item.Products != null && item.Products.Length > 0) { followup.Article = item.Products[0].Product_Name.Contents[0].Content; } else { followup.Article = ""; } if (item.TCode == "3") { followup.isAOKConfirmedStatus = true; } else { followup.isAOKConfirmedStatus = false; } List <GPOS> GPOS = new List <GPOS>(); GPOS gposData = new GPOS(); gposData.Number = item.GPOS; gposData.Text = "Nachsorgebehandlung"; if (followup.Article != "Ozurdex") { gposData.Price = 60; } else { gposData.Price = 150; } gposData.ID = 2; GPOS.Add(gposData); followup.GPOS = GPOS; OldFollowupsSorted.Add(followup); } foreach (var item in OldFollowupsSorted) { TreatmentsSorted.Add(item); } } #endregion #region get practice details P_L5PR_GPDfPID_1501 param = new P_L5PR_GPDfPID_1501(); param.PracticeID = listOfPractices.ToArray(); var practicesRawData = cls_Get_PracticeDetails_for_PracticeID.Invoke(Connection, Transaction, param, securityTicket).Result.ToList(); List <WordReportData> WordDataByPractice = new List <WordReportData>(); foreach (var practice in practicesRawData) { WordReportData wordData = new WordReportData(); wordData.PracticeID = practice.HEC_MedicalPractiseID; wordData.PracticeName = practice.PracticeName; wordData.PracticeAddress = practice.Street_Name + " " + practice.Street_Number; wordData.PracticePostalCodeAndCity = practice.ZIP + " " + practice.Town; wordData.SelectedMonth = Parameter.SelectedMounth_String; wordData.Treatments = TreatmentsSorted.Where(i => i.PracticeID == wordData.PracticeID).OrderBy(j => j.Date).ToList(); WordDataByPractice.Add(wordData); } #endregion //Make word documents by practice and attach the documents to email List <Attachment> atts = new List <Attachment>(); foreach (var practice in WordDataByPractice) { var parameters = new Dictionary <String, Object>(); parameters.Add("WordReportData", practice); parameters.Add("LanguageCode", Parameter.LanguageCode); parameters.Add("ReportType", "RTF"); string reportName = practice.PracticeName.Replace('/', '-'); var report = new LucentisReports.DoctorsBillingReport(); report.SetContext(parameters); MemoryStream ms1 = new MemoryStream(); ms1 = report.ExportToMemoryStream(); ms1.Seek(0, System.IO.SeekOrigin.Begin); Attachment att = new Attachment(ms1, "Doctors_Billing_" + reportName + "_" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm") + ".rtf", "application/doc"); atts.Add(att); } string[] toMails; string mailRes = (String)HttpContext.GetGlobalResourceObject("Global", "ReportMails"); #if DEBUG mailRes = (String)HttpContext.GetGlobalResourceObject("Global", "ReportMailsDebug"); #endif toMails = mailRes.Split(';'); string subjectRes = (String)HttpContext.GetGlobalResourceObject("Global", "ReportMailSubject1"); EmailUtils.SendMail(toMails, subjectRes, "", atts); return(returnValue); #endregion UserCode }
public GlyphSetPosition(Typeface typeface, string lang) { this.Lang = lang; this.typeface = typeface; //check if this lang has this.gposTable = typeface.GPOSTable; if (gposTable == null) { return; } ScriptTable scriptTable = gposTable.ScriptList[lang]; //--------- if (scriptTable == null) { return; } // early exit if no lookup tables //--------- ScriptTable.LangSysTable defaultLang = scriptTable.defaultLang; if (defaultLang == null) { return; } // early exit if no default language if (defaultLang.HasRequireFeature) { } //other feature if (defaultLang.featureIndexList != null) { //get features var features = new List <FeatureList.FeatureTable>(); for (int i = 0; i < defaultLang.featureIndexList.Length; ++i) { FeatureList.FeatureTable feature = gposTable.FeatureList.featureTables[defaultLang.featureIndexList[i]]; switch (feature.TagName) { case "mark": //mark=> mark to base case "mkmk": //mkmk => mark to mask //current version we implement this 2 features features.Add(feature); break; case "kern": //test with Candara font features.Add(feature); //If palt is activated, there is no requirement that kern must also be activated. //If kern is activated, palt must also be activated if it exists. //https://www.microsoft.com/typography/OTSpec/features_pt.htm#palt break; case "palt": break; default: break; } } //----------------------- lookupTables = new List <GPOS.LookupTable>(); int j = features.Count; for (int i = 0; i < j; ++i) { FeatureList.FeatureTable feature = features[i]; foreach (ushort lookupIndex in feature.LookupListIndices) { lookupTables.Add(gposTable.LookupList[lookupIndex]); } } } }
internal void Update(OS2Table os2Tabble, Meta meta, GSUB gsub, GPOS gpos) { //https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur //This field is used to specify the Unicode blocks or ranges encompassed by the font file in 'cmap' subtables for platform 3, //encoding ID 1 (Microsoft platform, Unicode BMP) and platform 3, //encoding ID 10 (Microsoft platform, Unicode full repertoire). //If a bit is set (1), then the Unicode ranges assigned to that bit are considered functional. //If the bit is clear (0), then the range is not considered functional. //unicode BMP (Basic Multilingual Plane),OR plane0 (see https://unicode.org/roadmaps/bmp/) //Each of the bits is treated as an independent flag and the bits can be set in any combination. //The determination of “functional” is left up to the font designer, //although character set selection should attempt to be functional by ranges if at all possible. //-------------- //Different versions of the OS/2 table were created when different Unicode versions were current, //and the initial specification for a given version defined fewer bit assignments than for later versions. //Some applications may not support all assignments for fonts that have earlier OS/2 versions. //All of the bit assignments listed above are valid for any version of the OS/2 table, //though OS/2 versions 1 and 2 were specified with some assignments that did not correspond to well-defined Unicode ranges and //that conflict with later assignments — see the details below. //If a font has a version 1 or version 2 OS/2 table with one of these bits set, //the obsolete assignment may be the intended interpretation. //Because these assignments do not correspond to well-defined ranges, //however, the implied character coverage is unclear. //Version 0: When version 0 was first specified, no bit assignments were defined. //Some applications may ignore these fields in a version 0 OS/2 table. //Version 1: //Version 1 was first specified concurrent with Unicode 1.1, //and bit assigments were defined for bits 0 to 69 only. With fonts that have a version 1 table, //some applications might recognize only bits 0 to 69. //Also, version 1 was specified with some bit assignments that did not correspond to a well-defined Unicode range: // Bit 8: “Greek Symbols and Coptic” (bit 7 was specified as “Basic Greek”) // Bit 12: “Hebrew Extended” (bit 11 was specified as “Basic Hebrew”) // Bit 14: “Arabic Extended” (bit 13 was specified as “Basic Arabic”) // Bit 27: “Georgian Extended” (bit 26 was specified as “Basic Georgian”) //These assignments were discontinued as of version 2. //In addition, versions 1 and 2 were defined with bit 53 specified as “CJK Miscellaneous”, //which also does not correspond to any well-defined Unicode range. //This assignment was discontinued as of version 3. //Version 2: //Version 2 was defined in OpenType 1.1, which was concurrent with Unicode 2.1. //At that time, bit assignments were defined for bits 0 to 69 only. //Bit assignments for version 2 were updated in OpenType 1.3, //adding assignments for bits 70 to 83 corresponding to new blocks assigned in Unicode 2.0 and Unicode 3.0. //With fonts that have a version 2 table, //some applications might recognize only those bits assigned in OpenType 1.2 or OpenType 1.3. //Also, the specification for version 2 continued to use a problematic assignment for bit 53 — //see details for version 1. This assignment was discontinued as of version 3. //Version 3: Version 3 was defined in OpenType 1.4 with assignments for bits 84 to 91 corresponding to additional //ranges in Unicode 3.2. //In addition, some already-assigned bits were extended to cover additional Unicode ranges for related characters; s //ee details in the table above. //Version 4: Version 4 was defined in OpenType 1.5 with assignments for bit 58 and bits 92 to 122 corresponding to additional ranges in Unicode 5.1. //Also, bits 8, 12, 14, 27 and 53 were re-assigned (see version 1 for previous assignments). //In addition, some already-assigned bits were extended to cover additional Unicode ranges for related characters; //see details in the table above. OS2Version = os2Tabble.version; UnicodeRange1 = os2Tabble.ulUnicodeRange1; UnicodeRange2 = os2Tabble.ulUnicodeRange2; UnicodeRange3 = os2Tabble.ulUnicodeRange3; UnicodeRange4 = os2Tabble.ulUnicodeRange4; //ULONG ulUnicodeRange1 Bits 0-31 //ULONG ulUnicodeRange2 Bits 32-63 //ULONG ulUnicodeRange3 Bits 64-95 //ULONG ulUnicodeRange4 Bits 96-127 //------- //IMPORTANT:*** //All available bits were exhausted as of Unicode 5.1. *** //The bit assignments were last updated for OS/2 version 4 in OpenType 1.5. //There are many additional ranges supported in the current version of Unicode that are not supported by these fields in the OS/2 table. // //See the 'dlng' and 'slng' tags in the 'meta' table for an alternate mechanism to declare //what scripts or languages that a font can support or is designed for. //------- if (meta != null) { SupportedLangs = meta.SupportedLanguageTags; DesignLangs = meta.DesignLanguageTags; } //---- //gsub and gpos contains actual script_list that are in the typeface GSUBScriptList = gsub?.ScriptList; GPOSScriptList = gpos?.ScriptList; }
public GlyphSetPosition(Typeface typeface, string lang) { this.Lang = lang; this.typeface = typeface; //check if this lang has this.gposTable = typeface.GPOSTable; if (gposTable == null) { return; } ScriptTable scriptTable = gposTable.ScriptList.FindScriptTable(lang); //--------- if (scriptTable == null) { return; } //early exit if no lookup tables //--------- ScriptTable.LangSysTable defaultLang = scriptTable.defaultLang; if (defaultLang.HasRequireFeature) { } //other feature if (defaultLang.featureIndexList != null) { //get features var features = new List <FeatureList.FeatureTable>(); for (int i = 0; i < defaultLang.featureIndexList.Length; ++i) { FeatureList.FeatureTable feature = gposTable.FeatureList.featureTables[defaultLang.featureIndexList[i]]; switch (feature.TagName) { case "mark": //mark=> mark to base case "mkmk": //mkmk => mark to mask //current version we implement this 2 features features.Add(feature); break; default: { } break; } } //----------------------- lookupTables = new List <GPOS.LookupTable>(); int j = features.Count; for (int i = 0; i < j; ++i) { FeatureList.FeatureTable feature = features[i]; ushort[] lookupListIndices = feature.LookupListIndice; foreach (ushort lookupIndex in lookupListIndices) { lookupTables.Add(gposTable.GetLookupTable(lookupIndex)); } } } }
public GlyphSetPosition(Typeface typeface, uint scriptTag, uint langTag) { this.ScriptTag = scriptTag; //script tag this.LangTag = langTag; //lang tag //check if this lang has _gposTable = typeface.GPOSTable; if (_gposTable == null) { return; } ScriptTable scriptTable = _gposTable.ScriptList[scriptTag]; if (scriptTable == null) { return; } // early exit if no lookup tables ScriptTable.LangSysTable selectedLang = scriptTable.defaultLang; if (selectedLang == null) { return; //no default } if (LangTag != 0 && scriptTable.langSysTables != null) //use default { //find matching lang for (int i = 0; i < scriptTable.langSysTables.Length; ++i) { if (scriptTable.langSysTables[i].langSysTagIden == LangTag) { //found selectedLang = scriptTable.langSysTables[i]; break; } } } #if DEBUG dbugTypeface = typeface; if (selectedLang.HasRequireFeature) { System.Diagnostics.Debugger.Break(); } #endif //other feature if (selectedLang.featureIndexList == null) { return; } // early exit //--------- //get features _lookupTables = new List <GPOS.LookupTable>(); for (int i = 0; i < selectedLang.featureIndexList.Length; ++i) { FeatureList.FeatureTable feature = _gposTable.FeatureList.featureTables[selectedLang.featureIndexList[i]]; bool includeThisFeature = false; switch (feature.TagName) { case "mark": //mark=> mark to base case "mkmk": //mkmk => mark to mask //current version we implement this 2 features includeThisFeature = true; break; case "kern": //test with Candara font includeThisFeature = true; //If palt is activated, there is no requirement that kern must also be activated. //If kern is activated, palt must also be activated if it exists. //https://www.microsoft.com/typography/OTSpec/features_pt.htm#palt break; //case "palt": // break; case "abvm": case "blwm": case "dist": includeThisFeature = true; break; default: System.Diagnostics.Debug.WriteLine("gpos_skip_tag:" + feature.TagName); break; } if (includeThisFeature) { foreach (ushort lookupIndex in feature.LookupListIndices) { _lookupTables.Add(_gposTable.LookupList[lookupIndex]); } } } }
internal bool ReadTableEntryCollection(Typeface typeface, RestoreTicket ticket, TableEntryCollection tables, BinaryReader input) { if (ticket != null) { return(ReadTableEntryCollectionOnRestoreMode(typeface, ticket, tables, input)); } typeface.SetTableEntryCollection(tables.CloneTableHeaders()); var rd = new EntriesReaderHelper(tables, input); //PART 1: basic information OS2Table os2Table = rd.Read(new OS2Table()); Meta meta = rd.Read(new Meta()); NameEntry nameEntry = rd.Read(new NameEntry()); Head head = rd.Read(new Head()); MaxProfile maxProfile = rd.Read(new MaxProfile()); HorizontalHeader horizontalHeader = rd.Read(new HorizontalHeader()); HorizontalMetrics horizontalMetrics = rd.Read(new HorizontalMetrics(horizontalHeader.NumberOfHMetrics, maxProfile.GlyphCount)); VerticalHeader vhea = rd.Read(new VerticalHeader()); if (vhea != null) { VerticalMetrics vmtx = rd.Read(new VerticalMetrics(vhea.NumOfLongVerMetrics)); } Cmap cmaps = rd.Read(new Cmap()); VerticalDeviceMetrics vdmx = rd.Read(new VerticalDeviceMetrics()); Kern kern = rd.Read(new Kern()); //------------------------------------ //PART 2: glyphs detail //2.1 True type font GlyphLocations glyphLocations = rd.Read(new GlyphLocations(maxProfile.GlyphCount, head.WideGlyphLocations)); Glyf glyf = rd.Read(new Glyf(glyphLocations)); Gasp gaspTable = rd.Read(new Gasp()); COLR colr = rd.Read(new COLR()); CPAL cpal = rd.Read(new CPAL()); //2.2 Cff font PostTable postTable = rd.Read(new PostTable()); CFFTable cff = rd.Read(new CFFTable()); //additional math table (if available) MathTable mathtable = rd.Read(new MathTable()); //------------------------------------ //PART 3: advanced typography GDEF gdef = rd.Read(new GDEF()); GSUB gsub = rd.Read(new GSUB()); GPOS gpos = rd.Read(new GPOS()); BASE baseTable = rd.Read(new BASE()); JSTF jstf = rd.Read(new JSTF()); STAT stat = rd.Read(new STAT()); if (stat != null) { //variable font FVar fvar = rd.Read(new FVar()); if (fvar != null) { GVar gvar = rd.Read(new GVar()); CVar cvar = rd.Read(new CVar()); HVar hvar = rd.Read(new HVar()); MVar mvar = rd.Read(new MVar()); AVar avar = rd.Read(new AVar()); } } bool isPostScriptOutline = false; bool isBitmapFont = false; typeface.SetBasicTypefaceTables(os2Table, nameEntry, head, horizontalMetrics); if (glyf == null) { //check if this is cff table ? if (cff == null) { //check cbdt/cblc ? CBLC cblcTable = rd.Read(new CBLC()); if (cblcTable != null) { CBDT cbdtTable = rd.Read(new CBDT()); //read cbdt //bitmap font BitmapFontGlyphSource bmpFontGlyphSrc = new BitmapFontGlyphSource(cblcTable); bmpFontGlyphSrc.LoadCBDT(cbdtTable); Glyph[] glyphs = bmpFontGlyphSrc.BuildGlyphList(); typeface.SetBitmapGlyphs(glyphs, bmpFontGlyphSrc); isBitmapFont = true; } else { //TODO: EBLC fontBmpTable = rd.Read(new EBLC()); throw new NotSupportedException(); } } else { isPostScriptOutline = true; typeface.SetCffFontSet(cff.Cff1FontSet); } } else { typeface.SetTtfGlyphs(glyf.Glyphs); } //---------------------------- typeface.CmapTable = cmaps; typeface.KernTable = kern; typeface.MaxProfile = maxProfile; typeface.HheaTable = horizontalHeader; //---------------------------- typeface.GaspTable = gaspTable; if (!isPostScriptOutline && !isBitmapFont) { //for true-type font outline FpgmTable fpgmTable = rd.Read(new FpgmTable()); //control values table CvtTable cvtTable = rd.Read(new CvtTable()); PrepTable propProgramTable = rd.Read(new PrepTable()); typeface.ControlValues = cvtTable?._controlValues; typeface.FpgmProgramBuffer = fpgmTable?._programBuffer; typeface.PrepProgramBuffer = propProgramTable?._programBuffer; } //------------------------- typeface.LoadOpenFontLayoutInfo( gdef, gsub, gpos, baseTable, colr, cpal); //------------ typeface.SetSvgTable(rd.Read(new SvgTable())); typeface.PostTable = postTable; if (mathtable != null) { MathGlyphLoader.LoadMathGlyph(typeface, mathtable); } #if DEBUG //test //int found = typeface.GetGlyphIndexByName("Uacute"); if (typeface.IsCffFont) { //optional typeface.UpdateAllCffGlyphBounds(); } #endif typeface.UpdateLangs(meta); typeface.UpdateFrequentlyUsedValues(); return(true); }