Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(744)

Side by Side Diff: src/ports/SkFontHost_mac.cpp

Issue 1590223003: Expose API for gx font variation axes. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix FontConfig and Android. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ports/SkFontHost_FreeType_common.h ('k') | src/ports/SkFontMgr_android.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkTypes.h" // Keep this before any #ifdef ... 9 #include "SkTypes.h" // Keep this before any #ifdef ...
10 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 10 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
(...skipping 2353 matching lines...) Expand 10 before | Expand all | Expand 10 after
2364 } 2364 }
2365 2365
2366 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov erride { 2366 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov erride {
2367 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea m)); 2367 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea m));
2368 if (nullptr == pr) { 2368 if (nullptr == pr) {
2369 return nullptr; 2369 return nullptr;
2370 } 2370 }
2371 return create_from_dataProvider(pr); 2371 return create_from_dataProvider(pr);
2372 } 2372 }
2373 2373
2374 static CFNumberRef get_tag_for_name(CFStringRef name, CFArrayRef ctAxes) {
2375 CFIndex ctAxisCount = CFArrayGetCount(ctAxes);
2376 for (int i = 0; i < ctAxisCount; ++i) {
2377 CFTypeRef ctAxisInfo = CFArrayGetValueAtIndex(ctAxes, i);
2378 if (CFDictionaryGetTypeID() != CFGetTypeID(ctAxisInfo)) {
2379 return nullptr;
2380 }
2381 CFDictionaryRef ctAxisInfoDict = static_cast<CFDictionaryRef>(ctAxis Info);
2382
2383 CFTypeRef ctAxisName = CFDictionaryGetValue(ctAxisInfoDict,
2384 kCTFontVariationAxisName Key);
2385 if (!ctAxisName || CFGetTypeID(ctAxisName) != CFStringGetTypeID()) {
2386 return nullptr;
2387 }
2388
2389 if (CFEqual(name, ctAxisName)) {
2390 CFTypeRef tag = CFDictionaryGetValue(ctAxisInfoDict,
2391 kCTFontVariationAxisIdentif ierKey);
2392 if (!tag || CFGetTypeID(tag) != CFNumberGetTypeID()) {
2393 return nullptr;
2394 }
2395 return static_cast<CFNumberRef>(tag);
2396 }
2397 }
2398 return nullptr;
2399 }
2400 static CFDictionaryRef get_axes(CGFontRef cg, const FontParameters& params) {
2401 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
2402 if (!cgAxes) {
2403 return nullptr;
2404 }
2405 CFIndex axisCount = CFArrayGetCount(cgAxes);
2406
2407 // The CGFont variation data is keyed by name, and lacks the tag.
2408 // The CTFont variation data is keyed by tag, and also has the name.
2409 // We would like to work with CTFont variaitons, but creating a CTFont f ont with
2410 // CTFont variation dictionary runs into bugs. So use the CTFont variati on data
2411 // to match names to tags to create the appropriate CGFont.
2412 AutoCFRelease<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr));
2413 AutoCFRelease<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct));
2414 if (!ctAxes || CFArrayGetCount(ctAxes) != axisCount) {
2415 return nullptr;
2416 }
2417
2418 int paramAxisCount;
2419 const FontParameters::Axis* paramAxes = params.getAxes(&paramAxisCount);
2420
2421 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefa ult, axisCount,
2422 &kCFTypeDictiona ryKeyCallBacks,
2423 &kCFTypeDictiona ryValueCallBacks);
2424 for (int i = 0; i < axisCount; ++i) {
2425 CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i);
2426 if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
2427 return nullptr;
2428 }
2429 CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo );
2430
2431 CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVaria tionAxisName);
2432 if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
2433 return nullptr;
2434 }
2435
2436 CFNumberRef tagNumber = get_tag_for_name(static_cast<CFStringRef>(ax isName), ctAxes);
2437 if (!tagNumber) {
2438 // Could not find a tag to go with the name of this index.
2439 // This would be a bug in CG/CT.
2440 continue;
2441 }
2442 int64_t tagLong;
2443 if (!CFNumberGetValue(tagNumber, kCFNumberSInt64Type, &tagLong)) {
2444 return nullptr;
2445 }
2446
2447 // The variation axes can be set to any value, but cg will effective ly pin them.
2448 // Pin them here to normalize.
2449 CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA xisMinValue);
2450 CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA xisMaxValue);
2451 CFTypeRef def = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA xisDefaultValue);
2452 if (!min || CFGetTypeID(min) != CFNumberGetTypeID() ||
2453 !max || CFGetTypeID(max) != CFNumberGetTypeID() ||
2454 !def || CFGetTypeID(def) != CFNumberGetTypeID())
2455 {
2456 return nullptr;
2457 }
2458 CFNumberRef minNumber = static_cast<CFNumberRef>(min);
2459 CFNumberRef maxNumber = static_cast<CFNumberRef>(max);
2460 CFNumberRef defNumber = static_cast<CFNumberRef>(def);
2461 double minDouble;
2462 double maxDouble;
2463 double defDouble;
2464 if (!CFNumberGetValue(minNumber, kCFNumberDoubleType, &minDouble) ||
2465 !CFNumberGetValue(maxNumber, kCFNumberDoubleType, &maxDouble) ||
2466 !CFNumberGetValue(defNumber, kCFNumberDoubleType, &defDouble))
2467 {
2468 return nullptr;
2469 }
2470
2471 double value = defDouble;
2472 for (int j = 0; j < paramAxisCount; ++j) {
2473 if (paramAxes[j].fTag == tagLong) {
2474 value = SkTPin(SkScalarToDouble(paramAxes[j].fStyleValue),mi nDouble,maxDouble);
2475 break;
2476 }
2477 }
2478 CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNum berDoubleType,
2479 &value);
2480 CFDictionaryAddValue(dict, axisName, valueNumber);
2481 CFRelease(valueNumber);
2482 }
2483 return dict;
2484 }
2485 SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& param s) const override {
2486 AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream (s));
2487 if (nullptr == provider) {
2488 return nullptr;
2489 }
2490 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
2491 if (nullptr == cg) {
2492 return nullptr;
2493 }
2494
2495 AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, params));
2496 // The CGFontRef returned by CGFontCreateCopyWithVariations when the pas sed CGFontRef was
2497 // created from a data provider does not appear to have any ownership of the underlying
2498 // data. The original CGFontRef must be kept alive until the copy will n o longer be used.
2499 AutoCFRelease<CGFontRef> cgVariant;
2500 if (cgVariations) {
2501 cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations));
2502 } else {
2503 cgVariant.reset(cg.detach());
2504 }
2505
2506 CTFontRef ct = CTFontCreateWithGraphicsFont(cgVariant, 0, nullptr, nullp tr);
2507 if (!ct) {
2508 return nullptr;
2509 }
2510 return NewFromFontRef(ct, cg.detach(), nullptr, true);
2511 }
2512
2374 static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) { 2513 static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) {
2375 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg)); 2514 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
2376 if (!cgAxes) { 2515 if (!cgAxes) {
2377 return nullptr; 2516 return nullptr;
2378 } 2517 }
2379 2518
2380 CFIndex axisCount = CFArrayGetCount(cgAxes); 2519 CFIndex axisCount = CFArrayGetCount(cgAxes);
2381 if (0 == axisCount || axisCount != fontData->getAxisCount()) { 2520 if (0 == axisCount || axisCount != fontData->getAxisCount()) {
2382 return nullptr; 2521 return nullptr;
2383 } 2522 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2488 } 2627 }
2489 return face; 2628 return face;
2490 } 2629 }
2491 }; 2630 };
2492 2631
2493 /////////////////////////////////////////////////////////////////////////////// 2632 ///////////////////////////////////////////////////////////////////////////////
2494 2633
2495 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } 2634 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; }
2496 2635
2497 #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 2636 #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
OLDNEW
« no previous file with comments | « src/ports/SkFontHost_FreeType_common.h ('k') | src/ports/SkFontMgr_android.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698