1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 4 * Copyright (C) 2013 Google Inc. All rights reserved. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #include "config.h" 24 #include "core/css/resolver/FontBuilder.h" 25 26 #include "core/css/CSSCalculationValue.h" 27 #include "core/css/CSSFontFeatureValue.h" 28 #include "core/css/CSSToLengthConversionData.h" 29 #include "core/css/FontSize.h" 30 #include "core/frame/LocalFrame.h" 31 #include "core/frame/Settings.h" 32 #include "core/rendering/RenderTheme.h" 33 #include "core/rendering/RenderView.h" 34 #include "platform/fonts/FontDescription.h" 35 #include "platform/text/LocaleToScriptMapping.h" 36 37 namespace WebCore { 38 39 // FIXME: This scoping class is a short-term fix to minimize the changes in 40 // Font-constructing logic. 41 class FontDescriptionChangeScope { 42 public: 43 FontDescriptionChangeScope(FontBuilder* fontBuilder) 44 : m_fontBuilder(fontBuilder) 45 , m_fontDescription(fontBuilder->m_style->fontDescription()) 46 { 47 } 48 49 void reset() { m_fontDescription = FontDescription(); } 50 void set(const FontDescription& fontDescription) { m_fontDescription = fontDescription; } 51 FontDescription& fontDescription() { return m_fontDescription; } 52 53 ~FontDescriptionChangeScope() 54 { 55 m_fontBuilder->didChangeFontParameters(m_fontBuilder->m_style->setFontDescription(m_fontDescription)); 56 } 57 58 private: 59 FontBuilder* m_fontBuilder; 60 FontDescription m_fontDescription; 61 }; 62 63 FontBuilder::FontBuilder() 64 : m_document(0) 65 , m_fontSizehasViewportUnits(false) 66 , m_style(0) 67 , m_fontDirty(false) 68 { 69 } 70 71 void FontBuilder::initForStyleResolve(const Document& document, RenderStyle* style) 72 { 73 ASSERT(document.frame()); 74 m_document = &document; 75 m_style = style; 76 m_fontDirty = false; 77 } 78 79 inline static void setFontFamilyToStandard(FontDescription& fontDescription, const Document* document) 80 { 81 if (!document || !document->settings()) 82 return; 83 84 fontDescription.setGenericFamily(FontDescription::StandardFamily); 85 const AtomicString& standardFontFamily = document->settings()->genericFontFamilySettings().standard(); 86 if (standardFontFamily.isEmpty()) 87 return; 88 89 fontDescription.firstFamily().setFamily(standardFontFamily); 90 // FIXME: Why is this needed here? 91 fontDescription.firstFamily().appendFamily(nullptr); 92 } 93 94 void FontBuilder::setInitial(float effectiveZoom) 95 { 96 ASSERT(m_document && m_document->settings()); 97 if (!m_document || !m_document->settings()) 98 return; 99 100 FontDescriptionChangeScope scope(this); 101 102 scope.reset(); 103 setFontFamilyToStandard(scope.fontDescription(), m_document); 104 scope.fontDescription().setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1); 105 setSize(scope.fontDescription(), effectiveZoom, FontSize::fontSizeForKeyword(m_document, CSSValueMedium, false)); 106 } 107 108 void FontBuilder::inheritFrom(const FontDescription& fontDescription) 109 { 110 FontDescriptionChangeScope scope(this); 111 112 scope.set(fontDescription); 113 } 114 115 void FontBuilder::didChangeFontParameters(bool changed) 116 { 117 m_fontDirty |= changed; 118 } 119 120 void FontBuilder::fromSystemFont(CSSValueID valueId, float effectiveZoom) 121 { 122 FontDescriptionChangeScope scope(this); 123 124 FontDescription fontDescription; 125 RenderTheme::theme().systemFont(valueId, fontDescription); 126 127 // Double-check and see if the theme did anything. If not, don't bother updating the font. 128 if (!fontDescription.isAbsoluteSize()) 129 return; 130 131 // Make sure the rendering mode and printer font settings are updated. 132 const Settings* settings = m_document->settings(); 133 ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings 134 if (!settings) 135 return; 136 137 // Handle the zoom factor. 138 fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription, effectiveZoom, fontDescription.specifiedSize())); 139 scope.set(fontDescription); 140 } 141 142 void FontBuilder::setFontFamilyInitial() 143 { 144 FontDescriptionChangeScope scope(this); 145 146 setFontFamilyToStandard(scope.fontDescription(), m_document); 147 } 148 149 void FontBuilder::setFontFamilyInherit(const FontDescription& parentFontDescription) 150 { 151 FontDescriptionChangeScope scope(this); 152 153 scope.fontDescription().setGenericFamily(parentFontDescription.genericFamily()); 154 scope.fontDescription().setFamily(parentFontDescription.family()); 155 } 156 157 // FIXME: I am not convinced FontBuilder needs to know anything about CSSValues. 158 void FontBuilder::setFontFamilyValue(CSSValue* value) 159 { 160 FontDescriptionChangeScope scope(this); 161 162 if (!value->isValueList()) 163 return; 164 165 FontFamily& firstFamily = scope.fontDescription().firstFamily(); 166 FontFamily* currFamily = 0; 167 168 // Before mapping in a new font-family property, we should reset the generic family. 169 bool oldFamilyUsedFixedDefaultSize = scope.fontDescription().useFixedDefaultSize(); 170 scope.fontDescription().setGenericFamily(FontDescription::NoFamily); 171 172 for (CSSValueListIterator i = value; i.hasMore(); i.advance()) { 173 CSSValue* item = i.value(); 174 if (!item->isPrimitiveValue()) 175 continue; 176 CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item); 177 AtomicString face; 178 Settings* settings = m_document->settings(); 179 if (contentValue->isString()) { 180 face = AtomicString(contentValue->getStringValue()); 181 } else if (settings) { 182 switch (contentValue->getValueID()) { 183 case CSSValueWebkitBody: 184 face = settings->genericFontFamilySettings().standard(); 185 break; 186 case CSSValueSerif: 187 face = FontFamilyNames::webkit_serif; 188 scope.fontDescription().setGenericFamily(FontDescription::SerifFamily); 189 break; 190 case CSSValueSansSerif: 191 face = FontFamilyNames::webkit_sans_serif; 192 scope.fontDescription().setGenericFamily(FontDescription::SansSerifFamily); 193 break; 194 case CSSValueCursive: 195 face = FontFamilyNames::webkit_cursive; 196 scope.fontDescription().setGenericFamily(FontDescription::CursiveFamily); 197 break; 198 case CSSValueFantasy: 199 face = FontFamilyNames::webkit_fantasy; 200 scope.fontDescription().setGenericFamily(FontDescription::FantasyFamily); 201 break; 202 case CSSValueMonospace: 203 face = FontFamilyNames::webkit_monospace; 204 scope.fontDescription().setGenericFamily(FontDescription::MonospaceFamily); 205 break; 206 case CSSValueWebkitPictograph: 207 face = FontFamilyNames::webkit_pictograph; 208 scope.fontDescription().setGenericFamily(FontDescription::PictographFamily); 209 break; 210 default: 211 break; 212 } 213 } 214 215 if (!face.isEmpty()) { 216 if (!currFamily) { 217 // Filling in the first family. 218 firstFamily.setFamily(face); 219 firstFamily.appendFamily(nullptr); // Remove any inherited family-fallback list. 220 currFamily = &firstFamily; 221 } else { 222 RefPtr<SharedFontFamily> newFamily = SharedFontFamily::create(); 223 newFamily->setFamily(face); 224 currFamily->appendFamily(newFamily); 225 currFamily = newFamily.get(); 226 } 227 } 228 } 229 230 // We can't call useFixedDefaultSize() until all new font families have been added 231 // If currFamily is non-zero then we set at least one family on this description. 232 if (!currFamily) 233 return; 234 235 if (scope.fontDescription().keywordSize() && scope.fontDescription().useFixedDefaultSize() != oldFamilyUsedFixedDefaultSize) 236 scope.fontDescription().setSpecifiedSize(FontSize::fontSizeForKeyword(m_document, CSSValueXxSmall + scope.fontDescription().keywordSize() - 1, !oldFamilyUsedFixedDefaultSize)); 237 } 238 239 void FontBuilder::setFontSizeInitial() 240 { 241 FontDescriptionChangeScope scope(this); 242 243 float size = FontSize::fontSizeForKeyword(m_document, CSSValueMedium, scope.fontDescription().useFixedDefaultSize()); 244 245 if (size < 0) 246 return; 247 248 scope.fontDescription().setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1); 249 scope.fontDescription().setSpecifiedSize(size); 250 } 251 252 void FontBuilder::setFontSizeInherit(const FontDescription& parentFontDescription) 253 { 254 FontDescriptionChangeScope scope(this); 255 256 float size = parentFontDescription.specifiedSize(); 257 258 if (size < 0) 259 return; 260 261 scope.fontDescription().setKeywordSize(parentFontDescription.keywordSize()); 262 scope.fontDescription().setSpecifiedSize(size); 263 } 264 265 // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) 266 // and scale down/up to the next size level. 267 static float largerFontSize(float size) 268 { 269 return size * 1.2f; 270 } 271 272 static float smallerFontSize(float size) 273 { 274 return size / 1.2f; 275 } 276 277 // FIXME: Have to pass RenderStyles here for calc/computed values. This shouldn't be neecessary. 278 void FontBuilder::setFontSizeValue(CSSValue* value, RenderStyle* parentStyle, const RenderStyle* rootElementStyle) 279 { 280 if (!value->isPrimitiveValue()) 281 return; 282 283 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); 284 285 FontDescriptionChangeScope scope(this); 286 287 scope.fontDescription().setKeywordSize(0); 288 float parentSize = 0; 289 bool parentIsAbsoluteSize = false; 290 float size = 0; 291 292 // FIXME: Find out when parentStyle could be 0? 293 if (parentStyle) { 294 parentSize = parentStyle->fontDescription().specifiedSize(); 295 parentIsAbsoluteSize = parentStyle->fontDescription().isAbsoluteSize(); 296 } 297 298 if (CSSValueID valueID = primitiveValue->getValueID()) { 299 switch (valueID) { 300 case CSSValueXxSmall: 301 case CSSValueXSmall: 302 case CSSValueSmall: 303 case CSSValueMedium: 304 case CSSValueLarge: 305 case CSSValueXLarge: 306 case CSSValueXxLarge: 307 case CSSValueWebkitXxxLarge: 308 size = FontSize::fontSizeForKeyword(m_document, valueID, scope.fontDescription().useFixedDefaultSize()); 309 scope.fontDescription().setKeywordSize(valueID - CSSValueXxSmall + 1); 310 break; 311 case CSSValueLarger: 312 size = largerFontSize(parentSize); 313 break; 314 case CSSValueSmaller: 315 size = smallerFontSize(parentSize); 316 break; 317 default: 318 return; 319 } 320 321 scope.fontDescription().setIsAbsoluteSize(parentIsAbsoluteSize && (valueID == CSSValueLarger || valueID == CSSValueSmaller)); 322 } else { 323 scope.fontDescription().setIsAbsoluteSize(parentIsAbsoluteSize || !(primitiveValue->isPercentage() || primitiveValue->isFontRelativeLength())); 324 if (primitiveValue->isPercentage()) { 325 size = (primitiveValue->getFloatValue() * parentSize) / 100.0f; 326 } else { 327 // If we have viewport units the conversion will mark the parent style as having viewport units. 328 bool parentHasViewportUnits = parentStyle->hasViewportUnits(); 329 parentStyle->setHasViewportUnits(false); 330 CSSToLengthConversionData conversionData(parentStyle, rootElementStyle, m_document->renderView(), 1.0f, true); 331 if (primitiveValue->isLength()) 332 size = primitiveValue->computeLength<float>(conversionData); 333 else if (primitiveValue->isCalculatedPercentageWithLength()) 334 size = primitiveValue->cssCalcValue()->toCalcValue(conversionData)->evaluate(parentSize); 335 else 336 ASSERT_NOT_REACHED(); 337 m_fontSizehasViewportUnits = parentStyle->hasViewportUnits(); 338 parentStyle->setHasViewportUnits(parentHasViewportUnits); 339 } 340 } 341 342 if (size < 0) 343 return; 344 345 // Overly large font sizes will cause crashes on some platforms (such as Windows). 346 // Cap font size here to make sure that doesn't happen. 347 size = std::min(maximumAllowedFontSize, size); 348 349 350 scope.fontDescription().setSpecifiedSize(size); 351 } 352 353 void FontBuilder::setWeight(FontWeight fontWeight) 354 { 355 FontDescriptionChangeScope scope(this); 356 357 scope.fontDescription().setWeight(fontWeight); 358 } 359 360 void FontBuilder::setWeightBolder() 361 { 362 FontDescriptionChangeScope scope(this); 363 364 scope.fontDescription().setWeight(scope.fontDescription().bolderWeight()); 365 } 366 367 void FontBuilder::setWeightLighter() 368 { 369 FontDescriptionChangeScope scope(this); 370 371 scope.fontDescription().setWeight(scope.fontDescription().lighterWeight()); 372 } 373 374 void FontBuilder::setFontVariantLigaturesInitial() 375 { 376 FontDescriptionChangeScope scope(this); 377 378 scope.fontDescription().setCommonLigaturesState(FontDescription::NormalLigaturesState); 379 scope.fontDescription().setDiscretionaryLigaturesState(FontDescription::NormalLigaturesState); 380 scope.fontDescription().setHistoricalLigaturesState(FontDescription::NormalLigaturesState); 381 scope.fontDescription().setContextualLigaturesState(FontDescription::NormalLigaturesState); 382 } 383 384 void FontBuilder::setFontVariantLigaturesInherit(const FontDescription& parentFontDescription) 385 { 386 FontDescriptionChangeScope scope(this); 387 388 scope.fontDescription().setCommonLigaturesState(parentFontDescription.commonLigaturesState()); 389 scope.fontDescription().setDiscretionaryLigaturesState(parentFontDescription.discretionaryLigaturesState()); 390 scope.fontDescription().setHistoricalLigaturesState(parentFontDescription.historicalLigaturesState()); 391 scope.fontDescription().setContextualLigaturesState(parentFontDescription.historicalLigaturesState()); 392 } 393 394 void FontBuilder::setFontVariantLigaturesValue(CSSValue* value) 395 { 396 FontDescriptionChangeScope scope(this); 397 398 FontDescription::LigaturesState commonLigaturesState = FontDescription::NormalLigaturesState; 399 FontDescription::LigaturesState discretionaryLigaturesState = FontDescription::NormalLigaturesState; 400 FontDescription::LigaturesState historicalLigaturesState = FontDescription::NormalLigaturesState; 401 FontDescription::LigaturesState contextualLigaturesState = FontDescription::NormalLigaturesState; 402 403 if (value->isValueList()) { 404 CSSValueList* valueList = toCSSValueList(value); 405 for (size_t i = 0; i < valueList->length(); ++i) { 406 CSSValue* item = valueList->itemWithoutBoundsCheck(i); 407 ASSERT(item->isPrimitiveValue()); 408 if (item->isPrimitiveValue()) { 409 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item); 410 switch (primitiveValue->getValueID()) { 411 case CSSValueNoCommonLigatures: 412 commonLigaturesState = FontDescription::DisabledLigaturesState; 413 break; 414 case CSSValueCommonLigatures: 415 commonLigaturesState = FontDescription::EnabledLigaturesState; 416 break; 417 case CSSValueNoDiscretionaryLigatures: 418 discretionaryLigaturesState = FontDescription::DisabledLigaturesState; 419 break; 420 case CSSValueDiscretionaryLigatures: 421 discretionaryLigaturesState = FontDescription::EnabledLigaturesState; 422 break; 423 case CSSValueNoHistoricalLigatures: 424 historicalLigaturesState = FontDescription::DisabledLigaturesState; 425 break; 426 case CSSValueHistoricalLigatures: 427 historicalLigaturesState = FontDescription::EnabledLigaturesState; 428 break; 429 case CSSValueNoContextual: 430 contextualLigaturesState = FontDescription::DisabledLigaturesState; 431 break; 432 case CSSValueContextual: 433 contextualLigaturesState = FontDescription::EnabledLigaturesState; 434 break; 435 default: 436 ASSERT_NOT_REACHED(); 437 break; 438 } 439 } 440 } 441 } 442 #if ASSERT_ENABLED 443 else { 444 ASSERT_WITH_SECURITY_IMPLICATION(value->isPrimitiveValue()); 445 ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal); 446 } 447 #endif 448 449 scope.fontDescription().setCommonLigaturesState(commonLigaturesState); 450 scope.fontDescription().setDiscretionaryLigaturesState(discretionaryLigaturesState); 451 scope.fontDescription().setHistoricalLigaturesState(historicalLigaturesState); 452 scope.fontDescription().setContextualLigaturesState(contextualLigaturesState); 453 } 454 455 void FontBuilder::setScript(const String& locale) 456 { 457 FontDescriptionChangeScope scope(this); 458 459 scope.fontDescription().setLocale(locale); 460 scope.fontDescription().setScript(localeToScriptCodeForFontSelection(locale)); 461 } 462 463 void FontBuilder::setStyle(FontStyle italic) 464 { 465 FontDescriptionChangeScope scope(this); 466 467 scope.fontDescription().setStyle(italic); 468 } 469 470 void FontBuilder::setVariant(FontVariant smallCaps) 471 { 472 FontDescriptionChangeScope scope(this); 473 474 scope.fontDescription().setVariant(smallCaps); 475 } 476 477 void FontBuilder::setTextRendering(TextRenderingMode textRenderingMode) 478 { 479 FontDescriptionChangeScope scope(this); 480 481 scope.fontDescription().setTextRendering(textRenderingMode); 482 } 483 484 void FontBuilder::setKerning(FontDescription::Kerning kerning) 485 { 486 FontDescriptionChangeScope scope(this); 487 488 scope.fontDescription().setKerning(kerning); 489 } 490 491 void FontBuilder::setFontSmoothing(FontSmoothingMode foontSmoothingMode) 492 { 493 FontDescriptionChangeScope scope(this); 494 495 scope.fontDescription().setFontSmoothing(foontSmoothingMode); 496 } 497 498 void FontBuilder::setFeatureSettingsNormal() 499 { 500 FontDescriptionChangeScope scope(this); 501 502 // FIXME: Eliminate FontDescription::makeNormalFeatureSettings. It's useless. 503 scope.set(scope.fontDescription().makeNormalFeatureSettings()); 504 } 505 506 void FontBuilder::setFeatureSettingsValue(CSSValue* value) 507 { 508 FontDescriptionChangeScope scope(this); 509 510 CSSValueList* list = toCSSValueList(value); 511 RefPtr<FontFeatureSettings> settings = FontFeatureSettings::create(); 512 int len = list->length(); 513 for (int i = 0; i < len; ++i) { 514 CSSValue* item = list->itemWithoutBoundsCheck(i); 515 if (!item->isFontFeatureValue()) 516 continue; 517 CSSFontFeatureValue* feature = toCSSFontFeatureValue(item); 518 settings->append(FontFeature(feature->tag(), feature->value())); 519 } 520 scope.fontDescription().setFeatureSettings(settings.release()); 521 } 522 523 void FontBuilder::setSize(FontDescription& fontDescription, float effectiveZoom, float size) 524 { 525 fontDescription.setSpecifiedSize(size); 526 fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription, effectiveZoom, size)); 527 } 528 529 float FontBuilder::getComputedSizeFromSpecifiedSize(FontDescription& fontDescription, float effectiveZoom, float specifiedSize) 530 { 531 float zoomFactor = effectiveZoom; 532 // FIXME: Why is this here!!!!?! 533 if (LocalFrame* frame = m_document->frame()) 534 zoomFactor *= frame->textZoomFactor(); 535 536 return FontSize::getComputedSizeFromSpecifiedSize(m_document, zoomFactor, fontDescription.isAbsoluteSize(), specifiedSize); 537 } 538 539 static void getFontAndGlyphOrientation(const RenderStyle* style, FontOrientation& fontOrientation, NonCJKGlyphOrientation& glyphOrientation) 540 { 541 if (style->isHorizontalWritingMode()) { 542 fontOrientation = Horizontal; 543 glyphOrientation = NonCJKGlyphOrientationVerticalRight; 544 return; 545 } 546 547 switch (style->textOrientation()) { 548 case TextOrientationVerticalRight: 549 fontOrientation = Vertical; 550 glyphOrientation = NonCJKGlyphOrientationVerticalRight; 551 return; 552 case TextOrientationUpright: 553 fontOrientation = Vertical; 554 glyphOrientation = NonCJKGlyphOrientationUpright; 555 return; 556 case TextOrientationSideways: 557 if (style->writingMode() == LeftToRightWritingMode) { 558 // FIXME: This should map to sideways-left, which is not supported yet. 559 fontOrientation = Vertical; 560 glyphOrientation = NonCJKGlyphOrientationVerticalRight; 561 return; 562 } 563 fontOrientation = Horizontal; 564 glyphOrientation = NonCJKGlyphOrientationVerticalRight; 565 return; 566 case TextOrientationSidewaysRight: 567 fontOrientation = Horizontal; 568 glyphOrientation = NonCJKGlyphOrientationVerticalRight; 569 return; 570 default: 571 ASSERT_NOT_REACHED(); 572 fontOrientation = Horizontal; 573 glyphOrientation = NonCJKGlyphOrientationVerticalRight; 574 return; 575 } 576 } 577 578 void FontBuilder::checkForOrientationChange(RenderStyle* style) 579 { 580 FontOrientation fontOrientation; 581 NonCJKGlyphOrientation glyphOrientation; 582 getFontAndGlyphOrientation(style, fontOrientation, glyphOrientation); 583 584 FontDescriptionChangeScope scope(this); 585 586 if (scope.fontDescription().orientation() == fontOrientation && scope.fontDescription().nonCJKGlyphOrientation() == glyphOrientation) 587 return; 588 589 scope.fontDescription().setNonCJKGlyphOrientation(glyphOrientation); 590 scope.fontDescription().setOrientation(fontOrientation); 591 } 592 593 void FontBuilder::checkForGenericFamilyChange(RenderStyle* style, const RenderStyle* parentStyle) 594 { 595 FontDescriptionChangeScope scope(this); 596 597 if (scope.fontDescription().isAbsoluteSize() || !parentStyle) 598 return; 599 600 const FontDescription& parentFontDescription = parentStyle->fontDescription(); 601 if (scope.fontDescription().useFixedDefaultSize() == parentFontDescription.useFixedDefaultSize()) 602 return; 603 604 // For now, lump all families but monospace together. 605 if (scope.fontDescription().genericFamily() != FontDescription::MonospaceFamily 606 && parentFontDescription.genericFamily() != FontDescription::MonospaceFamily) 607 return; 608 609 // We know the parent is monospace or the child is monospace, and that font 610 // size was unspecified. We want to scale our font size as appropriate. 611 // If the font uses a keyword size, then we refetch from the table rather than 612 // multiplying by our scale factor. 613 float size; 614 if (scope.fontDescription().keywordSize()) { 615 size = FontSize::fontSizeForKeyword(m_document, CSSValueXxSmall + scope.fontDescription().keywordSize() - 1, scope.fontDescription().useFixedDefaultSize()); 616 } else { 617 Settings* settings = m_document->settings(); 618 float fixedScaleFactor = (settings && settings->defaultFixedFontSize() && settings->defaultFontSize()) 619 ? static_cast<float>(settings->defaultFixedFontSize()) / settings->defaultFontSize() 620 : 1; 621 size = parentFontDescription.useFixedDefaultSize() ? 622 scope.fontDescription().specifiedSize() / fixedScaleFactor : 623 scope.fontDescription().specifiedSize() * fixedScaleFactor; 624 } 625 626 setSize(scope.fontDescription(), style->effectiveZoom(), size); 627 } 628 629 void FontBuilder::updateComputedSize(RenderStyle* style, const RenderStyle* parentStyle) 630 { 631 FontDescriptionChangeScope scope(this); 632 633 scope.fontDescription().setComputedSize(getComputedSizeFromSpecifiedSize(scope.fontDescription(), style->effectiveZoom(), scope.fontDescription().specifiedSize())); 634 } 635 636 // FIXME: style param should come first 637 void FontBuilder::createFont(PassRefPtrWillBeRawPtr<FontSelector> fontSelector, const RenderStyle* parentStyle, RenderStyle* style) 638 { 639 if (!m_fontDirty) 640 return; 641 642 updateComputedSize(style, parentStyle); 643 checkForGenericFamilyChange(style, parentStyle); 644 checkForOrientationChange(style); 645 style->font().update(fontSelector); 646 m_fontDirty = false; 647 } 648 649 void FontBuilder::createFontForDocument(PassRefPtrWillBeRawPtr<FontSelector> fontSelector, RenderStyle* documentStyle) 650 { 651 FontDescription fontDescription = FontDescription(); 652 fontDescription.setScript(localeToScriptCodeForFontSelection(documentStyle->locale())); 653 654 setFontFamilyToStandard(fontDescription, m_document); 655 fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1); 656 int size = FontSize::fontSizeForKeyword(m_document, CSSValueMedium, false); 657 fontDescription.setSpecifiedSize(size); 658 fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription, documentStyle->effectiveZoom(), size)); 659 660 FontOrientation fontOrientation; 661 NonCJKGlyphOrientation glyphOrientation; 662 getFontAndGlyphOrientation(documentStyle, fontOrientation, glyphOrientation); 663 fontDescription.setOrientation(fontOrientation); 664 fontDescription.setNonCJKGlyphOrientation(glyphOrientation); 665 documentStyle->setFontDescription(fontDescription); 666 documentStyle->font().update(fontSelector); 667 } 668 669 } 670