OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. |
3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) |
4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> | 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> | 5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> |
6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> | 6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> |
7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. | 8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. |
9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. |
10 * | 10 * |
(...skipping 2006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2017 void CanvasRenderingContext2D::strokeText(const String& text, float x, float y) | 2017 void CanvasRenderingContext2D::strokeText(const String& text, float x, float y) |
2018 { | 2018 { |
2019 drawTextInternal(text, x, y, false); | 2019 drawTextInternal(text, x, y, false); |
2020 } | 2020 } |
2021 | 2021 |
2022 void CanvasRenderingContext2D::strokeText(const String& text, float x, float y,
float maxWidth) | 2022 void CanvasRenderingContext2D::strokeText(const String& text, float x, float y,
float maxWidth) |
2023 { | 2023 { |
2024 drawTextInternal(text, x, y, false, maxWidth, true); | 2024 drawTextInternal(text, x, y, false, maxWidth, true); |
2025 } | 2025 } |
2026 | 2026 |
| 2027 static inline bool isSpaceCharacter(UChar c) |
| 2028 { |
| 2029 // According to specification all space characters should be replaced with 0
x0020 space character. |
| 2030 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-el
ement.html#text-preparation-algorithm |
| 2031 // The space characters according to specification are : U+0020, U+0009, U+0
00A, U+000C, and U+000D. |
| 2032 // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-micros
yntaxes.html#space-character |
| 2033 // This function returns true for 0x000B also, so that this is backward comp
atible. |
| 2034 // Otherwise, the test LayoutTests/canvas/philip/tests/2d.text.draw.space.co
llapse.space.html will fail |
| 2035 return c == 0x0009 || c == 0x000A || c == 0x000B || c == 0x000C || c == 0x00
0D; |
| 2036 } |
| 2037 |
| 2038 static String normalizeSpaces(const String& text) |
| 2039 { |
| 2040 unsigned textLength = text.length(); |
| 2041 Vector<UChar> charVector(textLength); |
| 2042 |
| 2043 for (unsigned i = 0; i < textLength; i++) { |
| 2044 if (isSpaceCharacter(text[i])) |
| 2045 charVector[i] = ' '; |
| 2046 else |
| 2047 charVector[i] = text[i]; |
| 2048 } |
| 2049 |
| 2050 return String(charVector); |
| 2051 } |
| 2052 |
2027 PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text
) | 2053 PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text
) |
2028 { | 2054 { |
2029 RefPtr<TextMetrics> metrics = TextMetrics::create(); | 2055 RefPtr<TextMetrics> metrics = TextMetrics::create(); |
2030 | 2056 |
2031 // The style resolution required for rendering text is not available in fram
e-less documents. | 2057 // The style resolution required for rendering text is not available in fram
e-less documents. |
2032 if (!canvas()->document().frame()) | 2058 if (!canvas()->document().frame()) |
2033 return metrics.release(); | 2059 return metrics.release(); |
2034 | 2060 |
2035 FontCachePurgePreventer fontCachePurgePreventer; | 2061 FontCachePurgePreventer fontCachePurgePreventer; |
2036 canvas()->document().updateRenderTreeIfNeeded(); | 2062 canvas()->document().updateRenderTreeIfNeeded(); |
2037 const Font& font = accessFont(); | 2063 const Font& font = accessFont(); |
2038 const TextRun textRun(text); | 2064 String normalizedText = normalizeSpaces(text); |
| 2065 const TextRun textRun(normalizedText); |
2039 FloatRect textBounds = font.selectionRectForText(textRun, FloatPoint(), font
.fontDescription().computedSize(), 0, -1, true); | 2066 FloatRect textBounds = font.selectionRectForText(textRun, FloatPoint(), font
.fontDescription().computedSize(), 0, -1, true); |
2040 | 2067 |
2041 // x direction | 2068 // x direction |
2042 metrics->setWidth(font.width(textRun)); | 2069 metrics->setWidth(font.width(textRun)); |
2043 metrics->setActualBoundingBoxLeft(-textBounds.x()); | 2070 metrics->setActualBoundingBoxLeft(-textBounds.x()); |
2044 metrics->setActualBoundingBoxRight(textBounds.maxX()); | 2071 metrics->setActualBoundingBoxRight(textBounds.maxX()); |
2045 | 2072 |
2046 // y direction | 2073 // y direction |
2047 const FontMetrics& fontMetrics = font.fontMetrics(); | 2074 const FontMetrics& fontMetrics = font.fontMetrics(); |
2048 const float ascent = fontMetrics.floatAscent(); | 2075 const float ascent = fontMetrics.floatAscent(); |
2049 const float descent = fontMetrics.floatDescent(); | 2076 const float descent = fontMetrics.floatDescent(); |
2050 const float baselineY = getFontBaseline(fontMetrics); | 2077 const float baselineY = getFontBaseline(fontMetrics); |
2051 | 2078 |
2052 metrics->setFontBoundingBoxAscent(ascent - baselineY); | 2079 metrics->setFontBoundingBoxAscent(ascent - baselineY); |
2053 metrics->setFontBoundingBoxDescent(descent + baselineY); | 2080 metrics->setFontBoundingBoxDescent(descent + baselineY); |
2054 metrics->setActualBoundingBoxAscent(-textBounds.y() - baselineY); | 2081 metrics->setActualBoundingBoxAscent(-textBounds.y() - baselineY); |
2055 metrics->setActualBoundingBoxDescent(textBounds.maxY() + baselineY); | 2082 metrics->setActualBoundingBoxDescent(textBounds.maxY() + baselineY); |
2056 | 2083 |
2057 // Note : top/bottom and ascend/descend are currently the same, so there's n
o difference | 2084 // Note : top/bottom and ascend/descend are currently the same, so there's n
o difference |
2058 // between the EM box's top and bottom and the font's ascend and desc
end | 2085 // between the EM box's top and bottom and the font's ascend and desc
end |
2059 metrics->setEmHeightAscent(0); | 2086 metrics->setEmHeightAscent(0); |
2060 metrics->setEmHeightDescent(0); | 2087 metrics->setEmHeightDescent(0); |
2061 | 2088 |
2062 metrics->setHangingBaseline(-0.8f * ascent + baselineY); | 2089 metrics->setHangingBaseline(-0.8f * ascent + baselineY); |
2063 metrics->setAlphabeticBaseline(baselineY); | 2090 metrics->setAlphabeticBaseline(baselineY); |
2064 metrics->setIdeographicBaseline(descent + baselineY); | 2091 metrics->setIdeographicBaseline(descent + baselineY); |
2065 return metrics.release(); | 2092 return metrics.release(); |
2066 } | 2093 } |
2067 | 2094 |
2068 static void replaceCharacterInString(String& text, WTF::CharacterMatchFunctionPt
r matchFunction, const String& replacement) | |
2069 { | |
2070 const size_t replacementLength = replacement.length(); | |
2071 size_t index = 0; | |
2072 while ((index = text.find(matchFunction, index)) != kNotFound) { | |
2073 text.replace(index, 1, replacement); | |
2074 index += replacementLength; | |
2075 } | |
2076 } | |
2077 | |
2078 void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
at y, bool fill, float maxWidth, bool useMaxWidth) | 2095 void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
at y, bool fill, float maxWidth, bool useMaxWidth) |
2079 { | 2096 { |
2080 // The style resolution required for rendering text is not available in fram
e-less documents. | 2097 // The style resolution required for rendering text is not available in fram
e-less documents. |
2081 if (!canvas()->document().frame()) | 2098 if (!canvas()->document().frame()) |
2082 return; | 2099 return; |
2083 | 2100 |
2084 // accessFont needs the style to be up to date, but updating style can cause
script to run, | 2101 // accessFont needs the style to be up to date, but updating style can cause
script to run, |
2085 // (e.g. due to autofocus) which can free the GraphicsContext, so update sty
le before grabbing | 2102 // (e.g. due to autofocus) which can free the GraphicsContext, so update sty
le before grabbing |
2086 // the GraphicsContext. | 2103 // the GraphicsContext. |
2087 canvas()->document().updateRenderTreeIfNeeded(); | 2104 canvas()->document().updateRenderTreeIfNeeded(); |
(...skipping 14 matching lines...) Expand all Loading... |
2102 return; | 2119 return; |
2103 | 2120 |
2104 gradient = c->fillGradient(); | 2121 gradient = c->fillGradient(); |
2105 if (fill && gradient && gradient->isZeroSize()) | 2122 if (fill && gradient && gradient->isZeroSize()) |
2106 return; | 2123 return; |
2107 | 2124 |
2108 FontCachePurgePreventer fontCachePurgePreventer; | 2125 FontCachePurgePreventer fontCachePurgePreventer; |
2109 | 2126 |
2110 const Font& font = accessFont(); | 2127 const Font& font = accessFont(); |
2111 const FontMetrics& fontMetrics = font.fontMetrics(); | 2128 const FontMetrics& fontMetrics = font.fontMetrics(); |
2112 // According to spec, all the space characters must be replaced with U+0020
SPACE characters. | 2129 String normalizedText = normalizeSpaces(text); |
2113 String normalizedText = text; | |
2114 replaceCharacterInString(normalizedText, isSpaceOrNewline, " "); | |
2115 | 2130 |
2116 // FIXME: Need to turn off font smoothing. | 2131 // FIXME: Need to turn off font smoothing. |
2117 | 2132 |
2118 RenderStyle* computedStyle = canvas()->computedStyle(); | 2133 RenderStyle* computedStyle = canvas()->computedStyle(); |
2119 TextDirection direction = computedStyle ? computedStyle->direction() : LTR; | 2134 TextDirection direction = computedStyle ? computedStyle->direction() : LTR; |
2120 bool isRTL = direction == RTL; | 2135 bool isRTL = direction == RTL; |
2121 bool override = computedStyle ? isOverride(computedStyle->unicodeBidi()) : f
alse; | 2136 bool override = computedStyle ? isOverride(computedStyle->unicodeBidi()) : f
alse; |
2122 | 2137 |
2123 TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direc
tion, override, true, TextRun::NoRounding); | 2138 TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direc
tion, override, true, TextRun::NoRounding); |
2124 // Draw the item text at the correct point. | 2139 // Draw the item text at the correct point. |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2370 c->setAlphaAsFloat(1.0); | 2385 c->setAlphaAsFloat(1.0); |
2371 c->clearShadow(); | 2386 c->clearShadow(); |
2372 c->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal); | 2387 c->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal); |
2373 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor); | 2388 c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor); |
2374 c->restore(); | 2389 c->restore(); |
2375 | 2390 |
2376 didDraw(dirtyRect); | 2391 didDraw(dirtyRect); |
2377 } | 2392 } |
2378 | 2393 |
2379 } // namespace WebCore | 2394 } // namespace WebCore |
OLD | NEW |