summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/android/FontAndroid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/android/FontAndroid.cpp')
-rw-r--r--WebCore/platform/graphics/android/FontAndroid.cpp208
1 files changed, 208 insertions, 0 deletions
diff --git a/WebCore/platform/graphics/android/FontAndroid.cpp b/WebCore/platform/graphics/android/FontAndroid.cpp
new file mode 100644
index 0000000..54a1a08
--- /dev/null
+++ b/WebCore/platform/graphics/android/FontAndroid.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Font.h"
+
+#include "FontData.h"
+#include "FontFallbackList.h"
+#include "GraphicsContext.h"
+#include "GlyphBuffer.h"
+#include "PlatformGraphicsContext.h"
+#include "IntRect.h"
+
+#include "SkCanvas.h"
+#include "SkLayerDrawLooper.h"
+#include "SkPaint.h"
+#include "SkTemplates.h"
+#include "SkTypeface.h"
+#include "SkUtils.h"
+
+namespace WebCore {
+
+static void updateForFont(SkPaint* paint, const SimpleFontData* font) {
+ font->platformData().setupPaint(paint);
+ paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+}
+
+static SkPaint* setupFill(SkPaint* paint, GraphicsContext* gc,
+ const SimpleFontData* font) {
+ gc->setupFillPaint(paint);
+ updateForFont(paint, font);
+ return paint;
+}
+
+static SkPaint* setupStroke(SkPaint* paint, GraphicsContext* gc,
+ const SimpleFontData* font) {
+ gc->setupStrokePaint(paint);
+ updateForFont(paint, font);
+ return paint;
+}
+
+static bool setupForText(SkPaint* paint, GraphicsContext* gc,
+ const SimpleFontData* font) {
+ int mode = gc->textDrawingMode();
+
+ if ((mode & (cTextFill | cTextStroke)) == (cTextFill | cTextStroke)) {
+ SkLayerDrawLooper* looper = new SkLayerDrawLooper;
+ paint->setLooper(looper)->unref();
+
+ // we clear the looper, in case we have a shadow
+
+ SkPaint* fillP = NULL;
+ SkPaint* strokeP = NULL;
+ if (gc->willStroke()) {
+ strokeP = setupStroke(looper->addLayer(), gc, font);
+ strokeP->setLooper(NULL);
+ }
+ if (gc->willFill()) {
+ fillP = setupFill(looper->addLayer(), gc, font);
+ fillP->setLooper(NULL);
+ }
+
+ SkPaint shadowPaint;
+ SkPoint offset;
+ if (gc->setupShadowPaint(&shadowPaint, &offset)) {
+ SkPaint* p = looper->addLayer(offset.fX, offset.fY);
+ *p = shadowPaint;
+ if (strokeP && !fillP) {
+ // stroke the shadow if we have stroke but no fill
+ p->setStyle(SkPaint::kStroke_Style);
+ p->setStrokeWidth(strokeP->getStrokeWidth());
+ }
+ updateForFont(p, font);
+ }
+ } else if (mode & cTextFill) {
+ (void)setupFill(paint, gc, font);
+ } else if (mode & cTextStroke) {
+ (void)setupStroke(paint, gc, font);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
+ const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
+ const FloatPoint& point) const {
+ SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t)); // compile-time assert
+
+ SkPaint paint;
+ if (!setupForText(&paint, gc, font)) {
+ return;
+ }
+
+ SkScalar x = SkFloatToScalar(point.x());
+ SkScalar y = SkFloatToScalar(point.y());
+ const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from);
+ const GlyphBufferAdvance* adv = glyphBuffer.advances(from);
+ SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
+ SkPoint* pos = storage.get();
+
+ /* We need an array of [x,y,x,y,x,y,...], but webkit is giving us
+ point.xy + [width, height, width, height, ...], so we have to convert
+ */
+ for (int i = 0; i < numGlyphs; i++) {
+ pos[i].set(x, y);
+ x += SkFloatToScalar(adv[i].width());
+ y += SkFloatToScalar(adv[i].height());
+ }
+
+ SkCanvas* canvas = gc->platformContext()->mCanvas;
+ canvas->drawPosText(glyphs, numGlyphs * sizeof(*glyphs), pos, paint);
+}
+
+FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, int, int) const
+{
+ SkPaint paint;
+ SkScalar width, left;
+ SkPaint::FontMetrics metrics;
+
+ primaryFont()->platformData().setupPaint(&paint);
+
+ width = paint.measureText(run.characters(), run.length() << 1);
+ SkScalar spacing = paint.getFontMetrics(&metrics);
+
+ return FloatRect(point.x(),
+ point.y() - floorf(SkScalarToFloat(-metrics.fAscent)),
+ roundf(SkScalarToFloat(width)),
+ roundf(SkScalarToFloat(spacing)));
+}
+
+void Font::drawComplexText(GraphicsContext* gc, TextRun const& run, FloatPoint const& point, int, int) const
+{
+ SkCanvas* canvas = gc->platformContext()->mCanvas;
+ SkPaint paint;
+
+ if (!setupForText(&paint, gc, primaryFont())) {
+ return;
+ }
+
+ // go to chars, instead of glyphs, which was set by setupForText()
+ paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
+
+ canvas->drawText(run.characters(), run.length() << 1,
+ SkFloatToScalar(point.x()), SkFloatToScalar(point.y()),
+ paint);
+}
+
+float Font::floatWidthForComplexText(const TextRun& run) const
+{
+ SkPaint paint;
+
+ primaryFont()->platformData().setupPaint(&paint);
+
+//printf("--------- complext measure %d chars\n", run.to() - run.from());
+
+ SkScalar width = paint.measureText(run.characters(), run.length() << 1);
+ return SkScalarToFloat(width);
+}
+
+int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool includePartialGlyphs) const
+{
+ SkPaint paint;
+ int count = run.length();
+ SkAutoSTMalloc<64, SkScalar> storage(count);
+ SkScalar* widths = storage.get();
+
+ primaryFont()->platformData().setupPaint(&paint);
+
+ count = paint.getTextWidths(run.characters(), count << 1, widths);
+
+ if (count > 0)
+ {
+ SkScalar pos = 0;
+ for (int i = 0; i < count; i++)
+ {
+ if (x < SkScalarRound(pos + SkScalarHalf(widths[i])))
+ return i;
+ pos += widths[i];
+ }
+ }
+ return count;
+}
+
+}