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

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

Issue 1873923002: Begin switch to SkFontStyle for legacy calls. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fixes, rebase. Created 4 years, 8 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
OLDNEW
1 /* 1 /*
2 * Copyright 2009-2015 Google Inc. 2 * Copyright 2009-2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 /* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */ 8 /* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */
9 9
10 #include "SkBuffer.h" 10 #include "SkBuffer.h"
11 #include "SkDataTable.h" 11 #include "SkDataTable.h"
12 #include "SkFixed.h"
12 #include "SkFontConfigInterface_direct.h" 13 #include "SkFontConfigInterface_direct.h"
13 #include "SkFontStyle.h" 14 #include "SkFontStyle.h"
14 #include "SkMutex.h" 15 #include "SkMutex.h"
15 #include "SkStream.h" 16 #include "SkStream.h"
16 #include "SkString.h" 17 #include "SkString.h"
17 #include "SkTArray.h" 18 #include "SkTArray.h"
18 #include "SkTDArray.h" 19 #include "SkTDArray.h"
19 #include "SkTemplates.h" 20 #include "SkTemplates.h"
20 #include "SkTypeface.h" 21 #include "SkTypeface.h"
21 #include "SkTypes.h" 22 #include "SkTypes.h"
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 // tells you whether a given request is for such a fallback. 298 // tells you whether a given request is for such a fallback.
298 bool IsFallbackFontAllowed(const SkString& family) { 299 bool IsFallbackFontAllowed(const SkString& family) {
299 const char* family_cstr = family.c_str(); 300 const char* family_cstr = family.c_str();
300 return family.isEmpty() || 301 return family.isEmpty() ||
301 strcasecmp(family_cstr, "sans") == 0 || 302 strcasecmp(family_cstr, "sans") == 0 ||
302 strcasecmp(family_cstr, "serif") == 0 || 303 strcasecmp(family_cstr, "serif") == 0 ||
303 strcasecmp(family_cstr, "monospace") == 0; 304 strcasecmp(family_cstr, "monospace") == 0;
304 } 305 }
305 306
306 // Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|. 307 // Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|.
308 #ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
307 SkTypeface::Style GetFontStyle(FcPattern* font) { 309 SkTypeface::Style GetFontStyle(FcPattern* font) {
308 int resulting_bold; 310 int resulting_bold;
309 if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold)) 311 if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold))
310 resulting_bold = FC_WEIGHT_NORMAL; 312 resulting_bold = FC_WEIGHT_NORMAL;
311 313
312 int resulting_italic; 314 int resulting_italic;
313 if (FcPatternGetInteger(font, FC_SLANT, 0, &resulting_italic)) 315 if (FcPatternGetInteger(font, FC_SLANT, 0, &resulting_italic))
314 resulting_italic = FC_SLANT_ROMAN; 316 resulting_italic = FC_SLANT_ROMAN;
315 317
316 // If we ask for an italic font, fontconfig might take a roman font and set 318 // If we ask for an italic font, fontconfig might take a roman font and set
(...skipping 11 matching lines...) Expand all
328 int styleBits = 0; 330 int styleBits = 0;
329 if (resulting_bold > FC_WEIGHT_MEDIUM && !have_embolden) { 331 if (resulting_bold > FC_WEIGHT_MEDIUM && !have_embolden) {
330 styleBits |= SkTypeface::kBold; 332 styleBits |= SkTypeface::kBold;
331 } 333 }
332 if (resulting_italic > FC_SLANT_ROMAN && !have_matrix) { 334 if (resulting_italic > FC_SLANT_ROMAN && !have_matrix) {
333 styleBits |= SkTypeface::kItalic; 335 styleBits |= SkTypeface::kItalic;
334 } 336 }
335 337
336 return (SkTypeface::Style)styleBits; 338 return (SkTypeface::Style)styleBits;
337 } 339 }
340 #else
341
342 static int get_int(FcPattern* pattern, const char object[], int missing) {
343 int value;
344 if (FcPatternGetInteger(pattern, object, 0, &value) != FcResultMatch) {
345 return missing;
346 }
347 return value;
348 }
349
350 static int map_range(SkFixed value,
351 SkFixed old_min, SkFixed old_max,
352 SkFixed new_min, SkFixed new_max)
353 {
354 SkASSERT(old_min < old_max);
355 SkASSERT(new_min <= new_max);
356 return new_min + SkMulDiv(value - old_min, new_max - new_min, old_max - old_ min);
357 }
358
359 static int ave(SkFixed a, SkFixed b) {
360 return SkFixedAve(a, b);
361 }
362
363 struct MapRanges {
364 SkFixed old_val;
365 SkFixed new_val;
366 };
367
368 static SkFixed map_ranges_fixed(SkFixed val, MapRanges const ranges[], int range sCount) {
369 // -Inf to [0]
370 if (val < ranges[0].old_val) {
371 return ranges[0].new_val;
372 }
373
374 // Linear from [i] to ave([i], [i+1]), then from ave([i], [i+1]) to [i+1]
375 for (int i = 0; i < rangesCount - 1; ++i) {
376 if (val < ave(ranges[i].old_val, ranges[i+1].old_val)) {
dogben 2016/04/11 20:28:58 I think you would get the same result if you just
bungeman-skia 2016/04/11 21:55:52 This was all copy-pasted from somewhere else, but
377 return map_range(val, ranges[i].old_val, ave(ranges[i].old_val, rang es[i+1].old_val),
378 ranges[i].new_val, ave(ranges[i].new_val, rang es[i+1].new_val));
379 }
380 if (val < ranges[i+1].old_val) {
381 return map_range(val, ave(ranges[i].old_val, ranges[i+1].old_val), r anges[i+1].old_val,
382 ave(ranges[i].new_val, ranges[i+1].new_val), r anges[i+1].new_val);
383 }
384 }
385
386 // From [n] to +Inf
387 // if (fcweight < Inf)
388 return ranges[rangesCount-1].new_val;
389 }
390
391 static int map_ranges(int val, MapRanges const ranges[], int rangesCount) {
392 return SkFixedRoundToInt(map_ranges_fixed(SkIntToFixed(val), ranges, rangesC ount));
393 }
394
395 template<int n> struct SkTFixed {
396 static_assert(-32768 <= n && n <= 32767, "SkTFixed_n_not_in_range");
397 static const SkFixed value = static_cast<SkFixed>(n << 16);
398 };
399
400 static SkFontStyle skfontstyle_from_fcpattern(FcPattern* pattern) {
401 typedef SkFontStyle SkFS;
402
403 static const MapRanges weightRanges[] = {
404 { SkTFixed<FC_WEIGHT_THIN>::value, SkTFixed<SkFS::kThin_Weight>::v alue },
405 { SkTFixed<FC_WEIGHT_EXTRALIGHT>::value, SkTFixed<SkFS::kExtraLight_Weig ht>::value },
406 { SkTFixed<FC_WEIGHT_LIGHT>::value, SkTFixed<SkFS::kLight_Weight>:: value },
407 { SkTFixed<FC_WEIGHT_REGULAR>::value, SkTFixed<SkFS::kNormal_Weight>: :value },
408 { SkTFixed<FC_WEIGHT_MEDIUM>::value, SkTFixed<SkFS::kMedium_Weight>: :value },
409 { SkTFixed<FC_WEIGHT_DEMIBOLD>::value, SkTFixed<SkFS::kSemiBold_Weight >::value },
410 { SkTFixed<FC_WEIGHT_BOLD>::value, SkTFixed<SkFS::kBold_Weight>::v alue },
411 { SkTFixed<FC_WEIGHT_EXTRABOLD>::value, SkTFixed<SkFS::kExtraBold_Weigh t>::value },
412 { SkTFixed<FC_WEIGHT_BLACK>::value, SkTFixed<SkFS::kBlack_Weight>:: value },
413 { SkTFixed<FC_WEIGHT_EXTRABLACK>::value, SkTFixed<1000>::value },
414 };
415 int weight = map_ranges(get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR),
416 weightRanges, SK_ARRAY_COUNT(weightRanges));
417
418 static const MapRanges widthRanges[] = {
419 { SkTFixed<FC_WIDTH_ULTRACONDENSED>::value, SkTFixed<SkFS::kUltraCondens ed_Width>::value },
420 { SkTFixed<FC_WIDTH_EXTRACONDENSED>::value, SkTFixed<SkFS::kExtraCondens ed_Width>::value },
421 { SkTFixed<FC_WIDTH_CONDENSED>::value, SkTFixed<SkFS::kCondensed_Wi dth>::value },
422 { SkTFixed<FC_WIDTH_SEMICONDENSED>::value, SkTFixed<SkFS::kSemiCondense d_Width>::value },
423 { SkTFixed<FC_WIDTH_NORMAL>::value, SkTFixed<SkFS::kNormal_Width >::value },
424 { SkTFixed<FC_WIDTH_SEMIEXPANDED>::value, SkTFixed<SkFS::kSemiExpanded _Width>::value },
425 { SkTFixed<FC_WIDTH_EXPANDED>::value, SkTFixed<SkFS::kExpanded_Wid th>::value },
426 { SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value, SkTFixed<SkFS::kExtraExpande d_Width>::value },
427 { SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value, SkTFixed<SkFS::kUltaExpanded _Width>::value },
428 };
429 int width = map_ranges(get_int(pattern, FC_WIDTH, FC_WIDTH_NORMAL),
430 widthRanges, SK_ARRAY_COUNT(widthRanges));
431
432 SkFS::Slant slant = get_int(pattern, FC_SLANT, FC_SLANT_ROMAN) > 0
433 ? SkFS::kItalic_Slant
434 : SkFS::kUpright_Slant;
435
436 return SkFontStyle(weight, width, slant);
437 }
438
439 static void fcpattern_from_skfontstyle(SkFontStyle style, FcPattern* pattern) {
440 typedef SkFontStyle SkFS;
441
442 static const MapRanges weightRanges[] = {
443 { SkTFixed<SkFS::kThin_Weight>::value, SkTFixed<FC_WEIGHT_THIN>::v alue },
444 { SkTFixed<SkFS::kExtraLight_Weight>::value, SkTFixed<FC_WEIGHT_EXTRALIG HT>::value },
445 { SkTFixed<SkFS::kLight_Weight>::value, SkTFixed<FC_WEIGHT_LIGHT>:: value },
446 { SkTFixed<SkFS::kNormal_Weight>::value, SkTFixed<FC_WEIGHT_REGULAR> ::value },
447 { SkTFixed<SkFS::kMedium_Weight>::value, SkTFixed<FC_WEIGHT_MEDIUM>: :value },
448 { SkTFixed<SkFS::kSemiBold_Weight>::value, SkTFixed<FC_WEIGHT_DEMIBOLD >::value },
449 { SkTFixed<SkFS::kBold_Weight>::value, SkTFixed<FC_WEIGHT_BOLD>::v alue },
450 { SkTFixed<SkFS::kExtraBold_Weight>::value, SkTFixed<FC_WEIGHT_EXTRABOL D>::value },
451 { SkTFixed<SkFS::kBlack_Weight>::value, SkTFixed<FC_WEIGHT_BLACK>:: value },
452 { SkTFixed<1000>::value, SkTFixed<FC_WEIGHT_EXTRABLA CK>::value },
453 };
454 int weight = map_ranges(style.weight(), weightRanges, SK_ARRAY_COUNT(weightR anges));
455
456 static const MapRanges widthRanges[] = {
457 { SkTFixed<SkFS::kUltraCondensed_Width>::value, SkTFixed<FC_WIDTH_ULTRAC ONDENSED>::value },
458 { SkTFixed<SkFS::kExtraCondensed_Width>::value, SkTFixed<FC_WIDTH_EXTRAC ONDENSED>::value },
459 { SkTFixed<SkFS::kCondensed_Width>::value, SkTFixed<FC_WIDTH_CONDEN SED>::value },
460 { SkTFixed<SkFS::kSemiCondensed_Width>::value, SkTFixed<FC_WIDTH_SEMICO NDENSED>::value },
461 { SkTFixed<SkFS::kNormal_Width>::value, SkTFixed<FC_WIDTH_NORMAL >::value },
462 { SkTFixed<SkFS::kSemiExpanded_Width>::value, SkTFixed<FC_WIDTH_SEMIEX PANDED>::value },
463 { SkTFixed<SkFS::kExpanded_Width>::value, SkTFixed<FC_WIDTH_EXPAND ED>::value },
464 { SkTFixed<SkFS::kExtraExpanded_Width>::value, SkTFixed<FC_WIDTH_EXTRAE XPANDED>::value },
465 { SkTFixed<SkFS::kUltaExpanded_Width>::value, SkTFixed<FC_WIDTH_ULTRAE XPANDED>::value },
466 };
467 int width = map_ranges(style.width(), widthRanges, SK_ARRAY_COUNT(widthRange s));
468
469 FcPatternAddInteger(pattern, FC_WEIGHT, weight);
470 FcPatternAddInteger(pattern, FC_WIDTH, width);
471 FcPatternAddInteger(pattern, FC_SLANT, style.isItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
472 }
473
474 SkFontStyle GetFontStyle(FcPattern* font) {
475 return skfontstyle_from_fcpattern(font);
476 }
477 #endif
338 478
339 } // anonymous namespace 479 } // anonymous namespace
340 480
341 /////////////////////////////////////////////////////////////////////////////// 481 ///////////////////////////////////////////////////////////////////////////////
342 482
343 #define kMaxFontFamilyLength 2048 483 #define kMaxFontFamilyLength 2048
344 484
345 SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() { 485 SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() {
346 SkAutoMutexAcquire ac(mutex_); 486 SkAutoMutexAcquire ac(mutex_);
347 487
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 if (acceptable_substitute) 550 if (acceptable_substitute)
411 break; 551 break;
412 } 552 }
413 if (!acceptable_substitute) 553 if (!acceptable_substitute)
414 return nullptr; 554 return nullptr;
415 } 555 }
416 556
417 return match; 557 return match;
418 } 558 }
419 559
560 #ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
420 bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], 561 bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
421 SkTypeface::Style style, 562 SkTypeface::Style style,
422 FontIdentity* outIdentity, 563 FontIdentity* outIdentity,
423 SkString* outFamilyName, 564 SkString* outFamilyName,
424 SkTypeface::Style* outStyle) { 565 SkTypeface::Style* outStyle) {
566 #else
567 bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
568 SkFontStyle style,
569 FontIdentity* outIdentity,
570 SkString* outFamilyName,
571 SkFontStyle* outStyle) {
572 #endif
425 SkString familyStr(familyName ? familyName : ""); 573 SkString familyStr(familyName ? familyName : "");
426 if (familyStr.size() > kMaxFontFamilyLength) { 574 if (familyStr.size() > kMaxFontFamilyLength) {
427 return false; 575 return false;
428 } 576 }
429 577
430 SkAutoMutexAcquire ac(mutex_); 578 SkAutoMutexAcquire ac(mutex_);
431 579
432 FcPattern* pattern = FcPatternCreate(); 580 FcPattern* pattern = FcPatternCreate();
433 581
434 if (familyName) { 582 if (familyName) {
435 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); 583 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
436 } 584 }
585 #ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
437 FcPatternAddInteger(pattern, FC_WEIGHT, 586 FcPatternAddInteger(pattern, FC_WEIGHT,
438 (style & SkTypeface::kBold) ? FC_WEIGHT_BOLD 587 (style & SkTypeface::kBold) ? FC_WEIGHT_BOLD
439 : FC_WEIGHT_NORMAL); 588 : FC_WEIGHT_NORMAL);
440 FcPatternAddInteger(pattern, FC_SLANT, 589 FcPatternAddInteger(pattern, FC_SLANT,
441 (style & SkTypeface::kItalic) ? FC_SLANT_ITALIC 590 (style & SkTypeface::kItalic) ? FC_SLANT_ITALIC
442 : FC_SLANT_ROMAN); 591 : FC_SLANT_ROMAN);
592 #else
593 fcpattern_from_skfontstyle(style, pattern);
594 #endif
595
443 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); 596 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
444 597
445 FcConfigSubstitute(nullptr, pattern, FcMatchPattern); 598 FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
446 FcDefaultSubstitute(pattern); 599 FcDefaultSubstitute(pattern);
447 600
448 // Font matching: 601 // Font matching:
449 // CSS often specifies a fallback list of families: 602 // CSS often specifies a fallback list of families:
450 // font-family: a, b, c, serif; 603 // font-family: a, b, c, serif;
451 // However, fontconfig will always do its best to find *a* font when asked 604 // However, fontconfig will always do its best to find *a* font when asked
452 // for something so we need a way to tell if the match which it has found is 605 // for something so we need a way to tell if the match which it has found is
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 const char* famName = get_name(match, FC_FAMILY); 728 const char* famName = get_name(match, FC_FAMILY);
576 if (famName && !find_name(names, famName)) { 729 if (famName && !find_name(names, famName)) {
577 *names.append() = famName; 730 *names.append() = famName;
578 *sizes.append() = strlen(famName) + 1; 731 *sizes.append() = strlen(famName) + 1;
579 } 732 }
580 } 733 }
581 734
582 return SkDataTable::NewCopyArrays((const void*const*)names.begin(), 735 return SkDataTable::NewCopyArrays((const void*const*)names.begin(),
583 sizes.begin(), names.count()); 736 sizes.begin(), names.count());
584 } 737 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698