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