< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.cc

Print this page

        

*** 24,42 **** * * Mozilla Author(s): Jonathan Kew * Google Author(s): Behdad Esfahbod */ ! #define HB_SHAPER coretext ! ! #include "hb-private.hh" ! #include "hb-debug.hh" ! #include "hb-shaper-impl-private.hh" #include "hb-coretext.h" #include <math.h> /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ #define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f static CGFloat coretext_font_size_from_ptem (float ptem) --- 24,50 ---- * * Mozilla Author(s): Jonathan Kew * Google Author(s): Behdad Esfahbod */ ! #include "hb.hh" ! #include "hb-shaper-impl.hh" #include "hb-coretext.h" + #include "hb-aat-layout.hh" #include <math.h> + + /** + * SECTION:hb-coretext + * @title: hb-coretext + * @short_description: CoreText integration + * @include: hb-coretext.h + * + * Functions for using HarfBuzz with the CoreText fonts. + **/ + /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ #define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f static CGFloat coretext_font_size_from_ptem (float ptem)
*** 89,105 **** { CGFontRelease ((CGFontRef) data); } - HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face) - HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font, - fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5 - ) - static CTFontDescriptorRef ! get_last_resort_font_desc (void) { // TODO Handle allocation failures? CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0); CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault, (const void **) &last_resort, --- 97,108 ---- { CGFontRelease ((CGFontRef) data); } static CTFontDescriptorRef ! get_last_resort_font_desc () { // TODO Handle allocation failures? CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0); CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault, (const void **) &last_resort,
*** 209,219 **** if (!isEmojiFont) return ct_font; } CFURLRef original_url = nullptr; ! #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 ATSFontRef atsFont; FSRef fsref; OSStatus status; atsFont = CTFontGetPlatformFont (ct_font, NULL); status = ATSFontGetFileReference (atsFont, &fsref); --- 212,222 ---- if (!isEmojiFont) return ct_font; } CFURLRef original_url = nullptr; ! #if TARGET_OS_OSX && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 ATSFontRef atsFont; FSRef fsref; OSStatus status; atsFont = CTFontGetPlatformFont (ct_font, NULL); status = ATSFontGetFileReference (atsFont, &fsref);
*** 239,249 **** * Avoid reconfiguring the cascade lists if the new font is outside the * system locations that we cannot access from the sandboxed renderer * process in Blink. This can be detected by the new file URL location * that the newly found font points to. */ CFURLRef new_url = nullptr; ! #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 atsFont = CTFontGetPlatformFont (new_ct_font, NULL); status = ATSFontGetFileReference (atsFont, &fsref); if (status == noErr) new_url = CFURLCreateFromFSRef (NULL, &fsref); #else --- 242,252 ---- * Avoid reconfiguring the cascade lists if the new font is outside the * system locations that we cannot access from the sandboxed renderer * process in Blink. This can be detected by the new file URL location * that the newly found font points to. */ CFURLRef new_url = nullptr; ! #if TARGET_OS_OSX && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 atsFont = CTFontGetPlatformFont (new_ct_font, NULL); status = ATSFontGetFileReference (atsFont, &fsref); if (status == noErr) new_url = CFURLCreateFromFSRef (NULL, &fsref); #else
*** 268,293 **** if (original_url) CFRelease (original_url); return ct_font; } ! hb_coretext_shaper_face_data_t * _hb_coretext_shaper_face_data_create (hb_face_t *face) { CGFontRef cg_font = create_cg_font (face); if (unlikely (!cg_font)) { DEBUG_MSG (CORETEXT, face, "CGFont creation failed.."); return nullptr; } ! return (hb_coretext_shaper_face_data_t *) cg_font; } void ! _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data) { CFRelease ((CGFontRef) data); } hb_face_t * --- 271,296 ---- if (original_url) CFRelease (original_url); return ct_font; } ! hb_coretext_face_data_t * _hb_coretext_shaper_face_data_create (hb_face_t *face) { CGFontRef cg_font = create_cg_font (face); if (unlikely (!cg_font)) { DEBUG_MSG (CORETEXT, face, "CGFont creation failed.."); return nullptr; } ! return (hb_coretext_face_data_t *) cg_font; } void ! _hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data) { CFRelease ((CGFontRef) data); } hb_face_t *
*** 300,338 **** * Since: 0.9.10 */ CGFontRef hb_coretext_face_get_cg_font (hb_face_t *face) { ! if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr; ! return (CGFontRef) HB_SHAPER_DATA_GET (face); } ! hb_coretext_shaper_font_data_t * _hb_coretext_shaper_font_data_create (hb_font_t *font) { hb_face_t *face = font->face; ! if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr; ! CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face); CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem)); if (unlikely (!ct_font)) { DEBUG_MSG (CORETEXT, font, "CGFont creation failed.."); return nullptr; } ! return (hb_coretext_shaper_font_data_t *) ct_font; } void ! _hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data) { CFRelease ((CTFontRef) data); } /* * Since: 1.7.2 */ hb_font_t * hb_coretext_font_create (CTFontRef ct_font) --- 303,373 ---- * Since: 0.9.10 */ CGFontRef hb_coretext_face_get_cg_font (hb_face_t *face) { ! return (CGFontRef) (const void *) face->data.coretext; } ! hb_coretext_font_data_t * _hb_coretext_shaper_font_data_create (hb_font_t *font) { hb_face_t *face = font->face; ! const hb_coretext_face_data_t *face_data = face->data.coretext; ! if (unlikely (!face_data)) return nullptr; ! CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext; CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem)); if (unlikely (!ct_font)) { DEBUG_MSG (CORETEXT, font, "CGFont creation failed.."); return nullptr; } ! return (hb_coretext_font_data_t *) ct_font; } void ! _hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data) { CFRelease ((CTFontRef) data); } + static const hb_coretext_font_data_t * + hb_coretext_font_data_sync (hb_font_t *font) + { + retry: + const hb_coretext_font_data_t *data = font->data.coretext; + if (unlikely (!data)) return nullptr; + + if (fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) > .5) + { + /* XXX-MT-bug + * Note that evaluating condition above can be dangerous if another thread + * got here first and destructed data. That's, as always, bad use pattern. + * If you modify the font (change font size), other threads must not be + * using it at the same time. However, since this check is delayed to + * when one actually tries to shape something, this is a XXX race condition + * (and the only one we have that I know of) right now. Ie. you modify the + * font size in one thread, then (supposedly safely) try to use it from two + * or more threads and BOOM! I'm not sure how to fix this. We want RCU. + */ + + /* Drop and recreate. */ + /* If someone dropped it in the mean time, throw it away and don't touch it. + * Otherwise, destruct it. */ + if (likely (font->data.coretext.cmpexch (const_cast<hb_coretext_font_data_t *> (data), nullptr))) + _hb_coretext_shaper_font_data_destroy (const_cast<hb_coretext_font_data_t *> (data)); + else + goto retry; + } + return font->data.coretext; + } + + /* * Since: 1.7.2 */ hb_font_t * hb_coretext_font_create (CTFontRef ct_font)
*** 341,389 **** hb_face_t *face = hb_coretext_face_create (cg_font); CFRelease (cg_font); hb_font_t *font = hb_font_create (face); hb_face_destroy (face); ! if (unlikely (hb_object_is_inert (font))) return font; hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font))); /* Let there be dragons here... */ ! HB_SHAPER_DATA_GET (font) = (hb_coretext_shaper_font_data_t *) CFRetain (ct_font); return font; } CTFontRef hb_coretext_font_get_ct_font (hb_font_t *font) { ! if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr; ! return (CTFontRef) HB_SHAPER_DATA_GET (font); ! } ! ! ! ! /* ! * shaper shape_plan data ! */ ! ! struct hb_coretext_shaper_shape_plan_data_t {}; ! ! hb_coretext_shaper_shape_plan_data_t * ! _hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, ! const hb_feature_t *user_features HB_UNUSED, ! unsigned int num_user_features HB_UNUSED, ! const int *coords HB_UNUSED, ! unsigned int num_coords HB_UNUSED) ! { ! return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; ! } ! ! void ! _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_t *data HB_UNUSED) ! { } /* * shaper --- 376,401 ---- hb_face_t *face = hb_coretext_face_create (cg_font); CFRelease (cg_font); hb_font_t *font = hb_font_create (face); hb_face_destroy (face); ! if (unlikely (hb_object_is_immutable (font))) return font; hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font))); /* Let there be dragons here... */ ! font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font)); return font; } CTFontRef hb_coretext_font_get_ct_font (hb_font_t *font) { ! const hb_coretext_font_data_t *data = hb_coretext_font_data_sync (font); ! return data ? (CTFontRef) data : nullptr; } /* * shaper
*** 430,633 **** unsigned int index_first; /* == start */ unsigned int index_last; /* == end - 1 */ }; - /* The following enum members are added in OS X 10.8. */ - #define kAltHalfWidthTextSelector 6 - #define kAltProportionalTextSelector 5 - #define kAlternateHorizKanaOffSelector 1 - #define kAlternateHorizKanaOnSelector 0 - #define kAlternateKanaType 34 - #define kAlternateVertKanaOffSelector 3 - #define kAlternateVertKanaOnSelector 2 - #define kCaseSensitiveLayoutOffSelector 1 - #define kCaseSensitiveLayoutOnSelector 0 - #define kCaseSensitiveLayoutType 33 - #define kCaseSensitiveSpacingOffSelector 3 - #define kCaseSensitiveSpacingOnSelector 2 - #define kContextualAlternatesOffSelector 1 - #define kContextualAlternatesOnSelector 0 - #define kContextualAlternatesType 36 - #define kContextualLigaturesOffSelector 19 - #define kContextualLigaturesOnSelector 18 - #define kContextualSwashAlternatesOffSelector 5 - #define kContextualSwashAlternatesOnSelector 4 - #define kDefaultLowerCaseSelector 0 - #define kDefaultUpperCaseSelector 0 - #define kHistoricalLigaturesOffSelector 21 - #define kHistoricalLigaturesOnSelector 20 - #define kHojoCharactersSelector 12 - #define kJIS2004CharactersSelector 11 - #define kLowerCasePetiteCapsSelector 2 - #define kLowerCaseSmallCapsSelector 1 - #define kLowerCaseType 37 - #define kMathematicalGreekOffSelector 11 - #define kMathematicalGreekOnSelector 10 - #define kNLCCharactersSelector 13 - #define kQuarterWidthTextSelector 4 - #define kScientificInferiorsSelector 4 - #define kStylisticAltEightOffSelector 17 - #define kStylisticAltEightOnSelector 16 - #define kStylisticAltEighteenOffSelector 37 - #define kStylisticAltEighteenOnSelector 36 - #define kStylisticAltElevenOffSelector 23 - #define kStylisticAltElevenOnSelector 22 - #define kStylisticAltFifteenOffSelector 31 - #define kStylisticAltFifteenOnSelector 30 - #define kStylisticAltFiveOffSelector 11 - #define kStylisticAltFiveOnSelector 10 - #define kStylisticAltFourOffSelector 9 - #define kStylisticAltFourOnSelector 8 - #define kStylisticAltFourteenOffSelector 29 - #define kStylisticAltFourteenOnSelector 28 - #define kStylisticAltNineOffSelector 19 - #define kStylisticAltNineOnSelector 18 - #define kStylisticAltNineteenOffSelector 39 - #define kStylisticAltNineteenOnSelector 38 - #define kStylisticAltOneOffSelector 3 - #define kStylisticAltOneOnSelector 2 - #define kStylisticAltSevenOffSelector 15 - #define kStylisticAltSevenOnSelector 14 - #define kStylisticAltSeventeenOffSelector 35 - #define kStylisticAltSeventeenOnSelector 34 - #define kStylisticAltSixOffSelector 13 - #define kStylisticAltSixOnSelector 12 - #define kStylisticAltSixteenOffSelector 33 - #define kStylisticAltSixteenOnSelector 32 - #define kStylisticAltTenOffSelector 21 - #define kStylisticAltTenOnSelector 20 - #define kStylisticAltThirteenOffSelector 27 - #define kStylisticAltThirteenOnSelector 26 - #define kStylisticAltThreeOffSelector 7 - #define kStylisticAltThreeOnSelector 6 - #define kStylisticAltTwelveOffSelector 25 - #define kStylisticAltTwelveOnSelector 24 - #define kStylisticAltTwentyOffSelector 41 - #define kStylisticAltTwentyOnSelector 40 - #define kStylisticAltTwoOffSelector 5 - #define kStylisticAltTwoOnSelector 4 - #define kStylisticAlternativesType 35 - #define kSwashAlternatesOffSelector 3 - #define kSwashAlternatesOnSelector 2 - #define kThirdWidthTextSelector 3 - #define kTraditionalNamesCharactersSelector 14 - #define kUpperCasePetiteCapsSelector 2 - #define kUpperCaseSmallCapsSelector 1 - #define kUpperCaseType 38 - - /* Table data courtesy of Apple. */ - static const struct feature_mapping_t { - FourCharCode otFeatureTag; - uint16_t aatFeatureType; - uint16_t selectorToEnable; - uint16_t selectorToDisable; - } feature_mappings[] = { - { 'c2pc', kUpperCaseType, kUpperCasePetiteCapsSelector, kDefaultUpperCaseSelector }, - { 'c2sc', kUpperCaseType, kUpperCaseSmallCapsSelector, kDefaultUpperCaseSelector }, - { 'calt', kContextualAlternatesType, kContextualAlternatesOnSelector, kContextualAlternatesOffSelector }, - { 'case', kCaseSensitiveLayoutType, kCaseSensitiveLayoutOnSelector, kCaseSensitiveLayoutOffSelector }, - { 'clig', kLigaturesType, kContextualLigaturesOnSelector, kContextualLigaturesOffSelector }, - { 'cpsp', kCaseSensitiveLayoutType, kCaseSensitiveSpacingOnSelector, kCaseSensitiveSpacingOffSelector }, - { 'cswh', kContextualAlternatesType, kContextualSwashAlternatesOnSelector, kContextualSwashAlternatesOffSelector }, - { 'dlig', kLigaturesType, kRareLigaturesOnSelector, kRareLigaturesOffSelector }, - { 'expt', kCharacterShapeType, kExpertCharactersSelector, 16 }, - { 'frac', kFractionsType, kDiagonalFractionsSelector, kNoFractionsSelector }, - { 'fwid', kTextSpacingType, kMonospacedTextSelector, 7 }, - { 'halt', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, - { 'hist', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, - { 'hkna', kAlternateKanaType, kAlternateHorizKanaOnSelector, kAlternateHorizKanaOffSelector, }, - { 'hlig', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, - { 'hngl', kTransliterationType, kHanjaToHangulSelector, kNoTransliterationSelector }, - { 'hojo', kCharacterShapeType, kHojoCharactersSelector, 16 }, - { 'hwid', kTextSpacingType, kHalfWidthTextSelector, 7 }, - { 'ital', kItalicCJKRomanType, kCJKItalicRomanOnSelector, kCJKItalicRomanOffSelector }, - { 'jp04', kCharacterShapeType, kJIS2004CharactersSelector, 16 }, - { 'jp78', kCharacterShapeType, kJIS1978CharactersSelector, 16 }, - { 'jp83', kCharacterShapeType, kJIS1983CharactersSelector, 16 }, - { 'jp90', kCharacterShapeType, kJIS1990CharactersSelector, 16 }, - { 'liga', kLigaturesType, kCommonLigaturesOnSelector, kCommonLigaturesOffSelector }, - { 'lnum', kNumberCaseType, kUpperCaseNumbersSelector, 2 }, - { 'mgrk', kMathematicalExtrasType, kMathematicalGreekOnSelector, kMathematicalGreekOffSelector }, - { 'nlck', kCharacterShapeType, kNLCCharactersSelector, 16 }, - { 'onum', kNumberCaseType, kLowerCaseNumbersSelector, 2 }, - { 'ordn', kVerticalPositionType, kOrdinalsSelector, kNormalPositionSelector }, - { 'palt', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'pcap', kLowerCaseType, kLowerCasePetiteCapsSelector, kDefaultLowerCaseSelector }, - { 'pkna', kTextSpacingType, kProportionalTextSelector, 7 }, - { 'pnum', kNumberSpacingType, kProportionalNumbersSelector, 4 }, - { 'pwid', kTextSpacingType, kProportionalTextSelector, 7 }, - { 'qwid', kTextSpacingType, kQuarterWidthTextSelector, 7 }, - { 'ruby', kRubyKanaType, kRubyKanaOnSelector, kRubyKanaOffSelector }, - { 'sinf', kVerticalPositionType, kScientificInferiorsSelector, kNormalPositionSelector }, - { 'smcp', kLowerCaseType, kLowerCaseSmallCapsSelector, kDefaultLowerCaseSelector }, - { 'smpl', kCharacterShapeType, kSimplifiedCharactersSelector, 16 }, - { 'ss01', kStylisticAlternativesType, kStylisticAltOneOnSelector, kStylisticAltOneOffSelector }, - { 'ss02', kStylisticAlternativesType, kStylisticAltTwoOnSelector, kStylisticAltTwoOffSelector }, - { 'ss03', kStylisticAlternativesType, kStylisticAltThreeOnSelector, kStylisticAltThreeOffSelector }, - { 'ss04', kStylisticAlternativesType, kStylisticAltFourOnSelector, kStylisticAltFourOffSelector }, - { 'ss05', kStylisticAlternativesType, kStylisticAltFiveOnSelector, kStylisticAltFiveOffSelector }, - { 'ss06', kStylisticAlternativesType, kStylisticAltSixOnSelector, kStylisticAltSixOffSelector }, - { 'ss07', kStylisticAlternativesType, kStylisticAltSevenOnSelector, kStylisticAltSevenOffSelector }, - { 'ss08', kStylisticAlternativesType, kStylisticAltEightOnSelector, kStylisticAltEightOffSelector }, - { 'ss09', kStylisticAlternativesType, kStylisticAltNineOnSelector, kStylisticAltNineOffSelector }, - { 'ss10', kStylisticAlternativesType, kStylisticAltTenOnSelector, kStylisticAltTenOffSelector }, - { 'ss11', kStylisticAlternativesType, kStylisticAltElevenOnSelector, kStylisticAltElevenOffSelector }, - { 'ss12', kStylisticAlternativesType, kStylisticAltTwelveOnSelector, kStylisticAltTwelveOffSelector }, - { 'ss13', kStylisticAlternativesType, kStylisticAltThirteenOnSelector, kStylisticAltThirteenOffSelector }, - { 'ss14', kStylisticAlternativesType, kStylisticAltFourteenOnSelector, kStylisticAltFourteenOffSelector }, - { 'ss15', kStylisticAlternativesType, kStylisticAltFifteenOnSelector, kStylisticAltFifteenOffSelector }, - { 'ss16', kStylisticAlternativesType, kStylisticAltSixteenOnSelector, kStylisticAltSixteenOffSelector }, - { 'ss17', kStylisticAlternativesType, kStylisticAltSeventeenOnSelector, kStylisticAltSeventeenOffSelector }, - { 'ss18', kStylisticAlternativesType, kStylisticAltEighteenOnSelector, kStylisticAltEighteenOffSelector }, - { 'ss19', kStylisticAlternativesType, kStylisticAltNineteenOnSelector, kStylisticAltNineteenOffSelector }, - { 'ss20', kStylisticAlternativesType, kStylisticAltTwentyOnSelector, kStylisticAltTwentyOffSelector }, - { 'subs', kVerticalPositionType, kInferiorsSelector, kNormalPositionSelector }, - { 'sups', kVerticalPositionType, kSuperiorsSelector, kNormalPositionSelector }, - { 'swsh', kContextualAlternatesType, kSwashAlternatesOnSelector, kSwashAlternatesOffSelector }, - { 'titl', kStyleOptionsType, kTitlingCapsSelector, kNoStyleOptionsSelector }, - { 'tnam', kCharacterShapeType, kTraditionalNamesCharactersSelector, 16 }, - { 'tnum', kNumberSpacingType, kMonospacedNumbersSelector, 4 }, - { 'trad', kCharacterShapeType, kTraditionalCharactersSelector, 16 }, - { 'twid', kTextSpacingType, kThirdWidthTextSelector, 7 }, - { 'unic', kLetterCaseType, 14, 15 }, - { 'valt', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'vert', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, - { 'vhal', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, - { 'vkna', kAlternateKanaType, kAlternateVertKanaOnSelector, kAlternateVertKanaOffSelector }, - { 'vpal', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'vrt2', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, - { 'zero', kTypographicExtrasType, kSlashedZeroOnSelector, kSlashedZeroOffSelector }, - }; - - static int - _hb_feature_mapping_cmp (const void *key_, const void *entry_) - { - unsigned int key = * (unsigned int *) key_; - const feature_mapping_t * entry = (const feature_mapping_t *) entry_; - return key < entry->otFeatureTag ? -1 : - key > entry->otFeatureTag ? 1 : - 0; - } - hb_bool_t _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, unsigned int num_features) { hb_face_t *face = font->face; ! CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face); ! CTFontRef ct_font = (CTFontRef) HB_SHAPER_DATA_GET (font); CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size; /* Attach marks to their bases, to match the 'ot' shaper. ! * Adapted from hb-ot-shape:hb_form_clusters(). * Note that this only makes us be closer to the 'ot' shaper, * but by no means the same. For example, if there's * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will * continue pointing to B2 even though B2 was merged into B1's * cluster... */ --- 442,468 ---- unsigned int index_first; /* == start */ unsigned int index_last; /* == end - 1 */ }; hb_bool_t _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, unsigned int num_features) { hb_face_t *face = font->face; ! CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext; ! CTFontRef ct_font = (CTFontRef) hb_coretext_font_data_sync (font); CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size; /* Attach marks to their bases, to match the 'ot' shaper. ! * Adapted from a very old version of hb-ot-shape:hb_form_clusters(). * Note that this only makes us be closer to the 'ot' shaper, * but by no means the same. For example, if there's * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will * continue pointing to B2 even though B2 was merged into B1's * cluster... */
*** 639,666 **** for (unsigned int i = 1; i < count; i++) if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (info[i].codepoint))) buffer->merge_clusters (i - 1, i + 1); } ! hb_auto_t<hb_vector_t<feature_record_t> > feature_records; ! hb_auto_t<hb_vector_t<range_record_t> > range_records; /* * Set up features. * (copied + modified from code from hb-uniscribe.cc) */ if (num_features) { /* Sort features by start/end events. */ ! hb_auto_t<hb_vector_t<feature_event_t> > feature_events; for (unsigned int i = 0; i < num_features; i++) { ! const feature_mapping_t * mapping = (const feature_mapping_t *) bsearch (&features[i].tag, ! feature_mappings, ! ARRAY_LENGTH (feature_mappings), ! sizeof (feature_mappings[0]), ! _hb_feature_mapping_cmp); if (!mapping) continue; active_feature_t feature; feature.rec.feature = mapping->aatFeatureType; --- 474,497 ---- for (unsigned int i = 1; i < count; i++) if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (info[i].codepoint))) buffer->merge_clusters (i - 1, i + 1); } ! hb_vector_t<feature_record_t> feature_records; ! hb_vector_t<range_record_t> range_records; /* * Set up features. * (copied + modified from code from hb-uniscribe.cc) */ if (num_features) { /* Sort features by start/end events. */ ! hb_vector_t<feature_event_t> feature_events; for (unsigned int i = 0; i < num_features; i++) { ! const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag); if (!mapping) continue; active_feature_t feature; feature.rec.feature = mapping->aatFeatureType;
*** 692,719 **** event->start = false; event->feature = feature; } /* Scan events and save features for each range. */ ! hb_auto_t<hb_vector_t<active_feature_t> > active_features; unsigned int last_index = 0; ! for (unsigned int i = 0; i < feature_events.len; i++) { feature_event_t *event = &feature_events[i]; if (event->index != last_index) { /* Save a snapshot of active features and the range. */ range_record_t *range = range_records.push (); ! if (active_features.len) { CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); /* TODO sort and resolve conflicting features? */ /* active_features.qsort (); */ ! for (unsigned int j = 0; j < active_features.len; j++) { CFStringRef keys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatureSelectorIdentifierKey }; --- 523,550 ---- event->start = false; event->feature = feature; } /* Scan events and save features for each range. */ ! hb_vector_t<active_feature_t> active_features; unsigned int last_index = 0; ! for (unsigned int i = 0; i < feature_events.length; i++) { feature_event_t *event = &feature_events[i]; if (event->index != last_index) { /* Save a snapshot of active features and the range. */ range_record_t *range = range_records.push (); ! if (active_features.length) { CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); /* TODO sort and resolve conflicting features? */ /* active_features.qsort (); */ ! for (unsigned int j = 0; j < active_features.length; j++) { CFStringRef keys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatureSelectorIdentifierKey };
*** 765,775 **** { active_features.push (event->feature); } else { active_feature_t *feature = active_features.find (&event->feature); if (feature) ! active_features.remove (feature - active_features.arrayZ); } } } unsigned int scratch_size; --- 596,606 ---- { active_features.push (event->feature); } else { active_feature_t *feature = active_features.find (&event->feature); if (feature) ! active_features.remove (feature - active_features.arrayZ ()); } } } unsigned int scratch_size;
*** 822,832 **** bool ret = true; CFStringRef string_ref = nullptr; CTLineRef line = nullptr; ! if (0) { resize_and_retry: DEBUG_MSG (CORETEXT, buffer, "Buffer resize"); /* string_ref uses the scratch-buffer for backing store, and line references * string_ref (via attr_string). We must release those before resizing buffer. */ --- 653,663 ---- bool ret = true; CFStringRef string_ref = nullptr; CTLineRef line = nullptr; ! if (false) { resize_and_retry: DEBUG_MSG (CORETEXT, buffer, "Buffer resize"); /* string_ref uses the scratch-buffer for backing store, and line references * string_ref (via attr_string). We must release those before resizing buffer. */
*** 897,907 **** CFRelease (lang); } CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), kCTFontAttributeName, ct_font); ! if (num_features && range_records.len) { unsigned int start = 0; range_record_t *last_range = &range_records[0]; for (unsigned int k = 0; k < chars_len; k++) { --- 728,738 ---- CFRelease (lang); } CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), kCTFontAttributeName, ct_font); ! if (num_features && range_records.length) { unsigned int start = 0; range_record_t *last_range = &range_records[0]; for (unsigned int k = 0; k < chars_len; k++) {
*** 1046,1056 **** * See: https://github.com/harfbuzz/harfbuzz/pull/36 * * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098 */ bool matched = false; ! for (unsigned int i = 0; i < range_records.len; i++) if (range_records[i].font && CFEqual (run_ct_font, range_records[i].font)) { matched = true; break; } --- 877,887 ---- * See: https://github.com/harfbuzz/harfbuzz/pull/36 * * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098 */ bool matched = false; ! for (unsigned int i = 0; i < range_records.length; i++) if (range_records[i].font && CFEqual (run_ct_font, range_records[i].font)) { matched = true; break; }
*** 1233,1243 **** * directions. As such, disable the assert... It wouldn't crash, but * cursoring will be off... * * https://crbug.com/419769 */ ! if (0) { /* Make sure all runs had the expected direction. */ bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); assert (bool (status_and & kCTRunStatusRightToLeft) == backward); assert (bool (status_or & kCTRunStatusRightToLeft) == backward); --- 1064,1074 ---- * directions. As such, disable the assert... It wouldn't crash, but * cursoring will be off... * * https://crbug.com/419769 */ ! if (false) { /* Make sure all runs had the expected direction. */ bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); assert (bool (status_and & kCTRunStatusRightToLeft) == backward); assert (bool (status_or & kCTRunStatusRightToLeft) == backward);
*** 1309,1319 **** if (string_ref) CFRelease (string_ref); if (line) CFRelease (line); ! for (unsigned int i = 0; i < range_records.len; i++) if (range_records[i].font) CFRelease (range_records[i].font); return ret; } --- 1140,1150 ---- if (string_ref) CFRelease (string_ref); if (line) CFRelease (line); ! for (unsigned int i = 0; i < range_records.length; i++) if (range_records[i].font) CFRelease (range_records[i].font); return ret; }
*** 1321,1400 **** /* * AAT shaper */ - HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, face) - HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, font) - /* * shaper face data */ ! struct hb_coretext_aat_shaper_face_data_t {}; ! hb_coretext_aat_shaper_face_data_t * _hb_coretext_aat_shaper_face_data_create (hb_face_t *face) { ! static const hb_tag_t tags[] = {HB_CORETEXT_TAG_MORX, HB_CORETEXT_TAG_MORT, HB_CORETEXT_TAG_KERX}; ! ! for (unsigned int i = 0; i < ARRAY_LENGTH (tags); i++) ! { ! hb_blob_t *blob = face->reference_table (tags[i]); ! if (hb_blob_get_length (blob)) ! { ! hb_blob_destroy (blob); ! return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr; ! } ! hb_blob_destroy (blob); ! } ! ! return nullptr; } void ! _hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *data HB_UNUSED) { } /* * shaper font data */ ! struct hb_coretext_aat_shaper_font_data_t {}; ! hb_coretext_aat_shaper_font_data_t * _hb_coretext_aat_shaper_font_data_create (hb_font_t *font) { ! return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr; ! } ! ! void ! _hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *data HB_UNUSED) ! { ! } ! ! ! /* ! * shaper shape_plan data ! */ ! ! struct hb_coretext_aat_shaper_shape_plan_data_t {}; ! ! hb_coretext_aat_shaper_shape_plan_data_t * ! _hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, ! const hb_feature_t *user_features HB_UNUSED, ! unsigned int num_user_features HB_UNUSED, ! const int *coords HB_UNUSED, ! unsigned int num_coords HB_UNUSED) ! { ! return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; } void ! _hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_plan_data_t *data HB_UNUSED) { } /* --- 1152,1194 ---- /* * AAT shaper */ /* * shaper face data */ ! struct hb_coretext_aat_face_data_t {}; ! hb_coretext_aat_face_data_t * _hb_coretext_aat_shaper_face_data_create (hb_face_t *face) { ! return hb_aat_layout_has_substitution (face) || hb_aat_layout_has_positioning (face) ? ! (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr; } void ! _hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_face_data_t *data HB_UNUSED) { } /* * shaper font data */ ! struct hb_coretext_aat_font_data_t {}; ! hb_coretext_aat_font_data_t * _hb_coretext_aat_shaper_font_data_create (hb_font_t *font) { ! return font->data.coretext ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr; } void ! _hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_font_data_t *data HB_UNUSED) { } /*
< prev index next >