Revert r170413 and r170390
[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 "Font.h"
28
29 #include "FontGlyphs.h"
30 #include "GlyphBuffer.h"
31 #include "GraphicsContext.h"
32 #include "IntRect.h"
33 #include "LayoutRect.h"
34 #include "Logging.h"
35 #include "SimpleFontData.h"
36 #include "TextRun.h"
37 #include "UniscribeController.h"
38 #include <wtf/MathExtras.h>
39
40 using namespace std;
41
42 namespace WebCore {
43
44 bool Font::canReturnFallbackFontsForComplexText()
45 {
46     return true;
47 }
48
49 bool Font::canExpandAroundIdeographsInComplexText()
50 {
51     return false;
52 }
53
54 void Font::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
55 {
56     UniscribeController it(this, run);
57     it.advance(from);
58     float beforeWidth = it.runWidthSoFar();
59     it.advance(to);
60     float afterWidth = it.runWidthSoFar();
61
62     if (run.rtl()) {
63         it.advance(run.length());
64         selectionRect.move(it.runWidthSoFar() - afterWidth, 0);
65     } else
66         selectionRect.move(beforeWidth, 0);
67     selectionRect.setWidth(afterWidth - beforeWidth);
68 }
69
70 float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
71 {
72     if (forTextEmphasis) {
73         // FIXME: Add forTextEmphasis paremeter to UniscribeController and use it.
74         LOG_ERROR("Not implemented for text emphasis.");
75         return 0;
76     }
77
78     UniscribeController controller(this, run);
79     controller.advance(from);
80     float beforeWidth = controller.runWidthSoFar();
81     controller.advance(to, &glyphBuffer);
82
83     if (glyphBuffer.isEmpty())
84         return 0;
85
86     float afterWidth = controller.runWidthSoFar();
87
88     if (run.rtl()) {
89         controller.advance(run.length());
90         return controller.runWidthSoFar() - afterWidth;
91     }
92     return beforeWidth;
93 }
94
95 float Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
96 {
97     // This glyph buffer holds our glyphs + advances + font data for each glyph.
98     GlyphBuffer glyphBuffer;
99
100     float startX = point.x() + getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer);
101
102     // We couldn't generate any glyphs for the run.  Give up.
103     if (glyphBuffer.isEmpty())
104         return 0;
105
106     // Draw the glyph buffer now at the starting point returned in startX.
107     FloatPoint startPoint(startX, point.y());
108     drawGlyphBuffer(context, run, glyphBuffer, startPoint);
109     return startPoint.x() - startX;
110 }
111
112 void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
113 {
114     GlyphBuffer glyphBuffer;
115     float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
116
117     if (glyphBuffer.isEmpty())
118         return;
119
120     drawEmphasisMarks(context, run, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
121 }
122
123 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
124 {
125     UniscribeController controller(this, run, fallbackFonts);
126     controller.advance(run.length());
127     if (glyphOverflow) {
128         glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().ascent()));
129         glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0  : fontMetrics().descent()));
130         glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX()));
131         glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.runWidthSoFar()));
132     }
133     return controller.runWidthSoFar();
134 }
135
136 int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, bool includePartialGlyphs) const
137 {
138     // FIXME: This truncation is not a problem for HTML, but only affects SVG, which passes floating-point numbers
139     // to Font::offsetForPosition(). Bug http://webkit.org/b/40673 tracks fixing this problem.
140     int x = static_cast<int>(xFloat);
141
142     UniscribeController controller(this, run);
143     return controller.offsetForPosition(x, includePartialGlyphs);
144 }
145
146 }