2396a4dee3dee150e7369f7e16a40d500f9ec9eb
[WebKit-https.git] / Source / WebCore / platform / graphics / win / FontWin.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "FontCascade.h"
28
29 #include "Font.h"
30 #include "GlyphBuffer.h"
31 #include "GraphicsContext.h"
32 #include "IntRect.h"
33 #include "LayoutRect.h"
34 #include "Logging.h"
35 #include "TextRun.h"
36 #include "UniscribeController.h"
37 #include <wtf/MathExtras.h>
38
39 using namespace std;
40
41 namespace WebCore {
42
43 bool FontCascade::canReturnFallbackFontsForComplexText()
44 {
45     return true;
46 }
47
48 bool FontCascade::canExpandAroundIdeographsInComplexText()
49 {
50     return false;
51 }
52
53 void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
54 {
55     UniscribeController it(this, run);
56     it.advance(from);
57     float beforeWidth = it.runWidthSoFar();
58     it.advance(to);
59     float afterWidth = it.runWidthSoFar();
60
61     if (run.rtl()) {
62         it.advance(run.length());
63         selectionRect.move(it.runWidthSoFar() - afterWidth, 0);
64     } else
65         selectionRect.move(beforeWidth, 0);
66     selectionRect.setWidth(afterWidth - beforeWidth);
67 }
68
69 float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
70 {
71     if (forTextEmphasis) {
72         // FIXME: Add forTextEmphasis paremeter to UniscribeController and use it.
73         LOG_ERROR("Not implemented for text emphasis.");
74         return 0;
75     }
76
77     UniscribeController controller(this, run);
78     controller.advance(from);
79     float beforeWidth = controller.runWidthSoFar();
80     controller.advance(to, &glyphBuffer);
81
82     if (glyphBuffer.isEmpty())
83         return 0;
84
85     float afterWidth = controller.runWidthSoFar();
86
87     if (run.rtl()) {
88         controller.advance(run.length());
89         return controller.runWidthSoFar() - afterWidth;
90     }
91     return beforeWidth;
92 }
93
94 void FontCascade::drawEmphasisMarksForComplexText(GraphicsContext& context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
95 {
96     GlyphBuffer glyphBuffer;
97     float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
98
99     if (glyphBuffer.isEmpty())
100         return;
101
102     drawEmphasisMarks(context, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
103 }
104
105 float FontCascade::floatWidthForComplexText(const TextRun& run, HashSet<const Font*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
106 {
107     UniscribeController controller(this, run, fallbackFonts);
108     controller.advance(run.length());
109     if (glyphOverflow) {
110         glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().ascent()));
111         glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0  : fontMetrics().descent()));
112         glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX()));
113         glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.runWidthSoFar()));
114     }
115     return controller.runWidthSoFar();
116 }
117
118 int FontCascade::offsetForPositionForComplexText(const TextRun& run, float xFloat, bool includePartialGlyphs) const
119 {
120     // FIXME: This truncation is not a problem for HTML, but only affects SVG, which passes floating-point numbers
121     // to FontCascade::offsetForPosition(). Bug http://webkit.org/b/40673 tracks fixing this problem.
122     int x = static_cast<int>(xFloat);
123
124     UniscribeController controller(this, run);
125     return controller.offsetForPosition(x, includePartialGlyphs);
126 }
127
128 }