1 /* 2 * Copyright (C) 2006, 2007, 2008, 2009 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. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 #include "config.h" 26 #include "Font.h" 27 28 #include "ComplexTextController.h" 29 #include "FontFallbackList.h" 30 #include "GlyphBuffer.h" 31 #include "GraphicsContext.h" 32 #include "IntRect.h" 33 #include "SimpleFontData.h" 34 #include <wtf/MathExtras.h> 35 36 namespace WebCore { 37 38 FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, 39 int from, int to) const 40 { 41 ComplexTextController controller(this, run); 42 controller.advance(from); 43 float beforeWidth = controller.runWidthSoFar(); 44 controller.advance(to); 45 float afterWidth = controller.runWidthSoFar(); 46 47 // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning 48 if (run.rtl()) { 49 float totalWidth = controller.totalWidth(); 50 return FloatRect(point.x() + floorf(totalWidth - afterWidth), point.y(), roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), h); 51 } 52 53 return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h); 54 } 55 56 void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, 57 int from, int to) const 58 { 59 // This glyph buffer holds our glyphs + advances + font data for each glyph. 60 GlyphBuffer glyphBuffer; 61 62 float startX = point.x(); 63 ComplexTextController controller(this, run); 64 controller.advance(from); 65 float beforeWidth = controller.runWidthSoFar(); 66 controller.advance(to, &glyphBuffer); 67 68 // We couldn't generate any glyphs for the run. Give up. 69 if (glyphBuffer.isEmpty()) 70 return; 71 72 float afterWidth = controller.runWidthSoFar(); 73 74 if (run.rtl()) { 75 startX += controller.totalWidth() + controller.finalRoundingWidth() - afterWidth; 76 for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end) 77 glyphBuffer.swap(i, end); 78 } else 79 startX += beforeWidth; 80 81 // Draw the glyph buffer now at the starting point returned in startX. 82 FloatPoint startPoint(startX, point.y()); 83 drawGlyphBuffer(context, glyphBuffer, run, startPoint); 84 } 85 86 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) const 87 { 88 ComplexTextController controller(this, run, true, fallbackFonts); 89 return controller.totalWidth(); 90 } 91 92 int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool includePartialGlyphs) const 93 { 94 ComplexTextController controller(this, run); 95 return controller.offsetForPosition(x, includePartialGlyphs); 96 } 97 98 } // namespace WebCore 99