MinikinUtils.cpp revision 7c93e868825225a270c993ac058687adde682626
11a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien/*
21a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Copyright (C) 2014 The Android Open Source Project
31a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien *
41a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Licensed under the Apache License, Version 2.0 (the "License");
51a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * you may not use this file except in compliance with the License.
61a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * You may obtain a copy of the License at
71a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien *
81a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien *      http://www.apache.org/licenses/LICENSE-2.0
91a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien *
101a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Unless required by applicable law or agreed to in writing, software
111a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * distributed under the License is distributed on an "AS IS" BASIS,
121a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * See the License for the specific language governing permissions and
141a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * limitations under the License.
151a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien */
1652eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn
17dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include "MinikinUtils.h"
181a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
1952eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <string>
2052eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn
2152eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <log/log.h>
2252eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn
23afbd0f1fef46ef0ddf633dfde0de724db3da1405Sergei Vasilinetc#include "Paint.h"
24dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include "SkPathMeasure.h"
25bad99183916ba2bac6659efc8a28273e344ba511sergeyv#include "Typeface.h"
261a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
271a73f732f91e97c9c66b808c245ddda36a10e987Raph Leviennamespace android {
281a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
29ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonakaminikin::FontStyle MinikinUtils::prepareMinikinPaint(minikin::MinikinPaint* minikinPaint,
30318ca04079bd6242cb6186d9005b9caeee22e845Seigo Nonaka        const Paint* paint, const Typeface* typeface) {
31bad99183916ba2bac6659efc8a28273e344ba511sergeyv    const Typeface* resolvedFace = Typeface::resolveDefault(typeface);
32ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    minikin::FontStyle resolved = resolvedFace->fStyle;
335ec789608bda858a0c6d669bb44a35a5a99abcdbBehdad Esfahbod
345ec789608bda858a0c6d669bb44a35a5a99abcdbBehdad Esfahbod    /* Prepare minikin FontStyle */
35ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    minikin::FontVariant minikinVariant = (paint->getFontVariant() == minikin::VARIANT_ELEGANT) ?
36ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka            minikin::VARIANT_ELEGANT : minikin::VARIANT_COMPACT;
37cfc607cf57d453f977c9c4bf09b41ac481c4bbecSeigo Nonaka    const uint32_t langListId = paint->getMinikinLangListId();
38ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    minikin::FontStyle minikinStyle(langListId, minikinVariant, resolved.getWeight(),
39ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka            resolved.getItalic());
405ec789608bda858a0c6d669bb44a35a5a99abcdbBehdad Esfahbod
415ec789608bda858a0c6d669bb44a35a5a99abcdbBehdad Esfahbod    /* Prepare minikin Paint */
42a130a6cf4cf9f8294dcd95b94ed6e45bbddbfe40Seigo Nonaka    minikinPaint->size = paint->isLinearText() ?
43a130a6cf4cf9f8294dcd95b94ed6e45bbddbfe40Seigo Nonaka            paint->getTextSize() : static_cast<int>(paint->getTextSize());
44c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien    minikinPaint->scaleX = paint->getTextScaleX();
45c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien    minikinPaint->skewX = paint->getTextSkewX();
46c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien    minikinPaint->letterSpacing = paint->getLetterSpacing();
47219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka    minikinPaint->wordSpacing = paint->getWordSpacing();
48c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien    minikinPaint->paintFlags = MinikinFontSkia::packPaintFlags(paint);
49c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien    minikinPaint->fontFeatureSettings = paint->getFontFeatureSettings();
50ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    minikinPaint->hyphenEdit = minikin::HyphenEdit(paint->getHyphenEdit());
51c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien    return minikinStyle;
52c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien}
535ec789608bda858a0c6d669bb44a35a5a99abcdbBehdad Esfahbod
547c93e868825225a270c993ac058687adde682626Seigo Nonakaminikin::Layout MinikinUtils::doLayout(const Paint* paint, minikin::Bidi bidiFlags,
557c93e868825225a270c993ac058687adde682626Seigo Nonaka        const Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize) {
56ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    minikin::MinikinPaint minikinPaint;
57c7064146f959caec058980ced144942c8044a169Seigo Nonaka    minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, paint, typeface);
5851218e80f70601193e43d90aaf1599a7f6d11062Seigo Nonaka    minikin::Layout layout;
5951218e80f70601193e43d90aaf1599a7f6d11062Seigo Nonaka    layout.doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint,
6051218e80f70601193e43d90aaf1599a7f6d11062Seigo Nonaka            Typeface::resolveDefault(typeface)->fFontCollection);
61c7064146f959caec058980ced144942c8044a169Seigo Nonaka    return layout;
621a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien}
631a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
647c93e868825225a270c993ac058687adde682626Seigo Nonakafloat MinikinUtils::measureText(const Paint* paint, minikin::Bidi bidiFlags,
657c93e868825225a270c993ac058687adde682626Seigo Nonaka        const Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize,
667c93e868825225a270c993ac058687adde682626Seigo Nonaka        float *advances) {
67ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    minikin::MinikinPaint minikinPaint;
68c7064146f959caec058980ced144942c8044a169Seigo Nonaka    minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, paint, typeface);
69318ca04079bd6242cb6186d9005b9caeee22e845Seigo Nonaka    const Typeface* resolvedTypeface = Typeface::resolveDefault(typeface);
70ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka    return minikin::Layout::measureText(buf, start, count, bufSize, bidiFlags, minikinStyle,
710aa07a712984a655215f20e664915b67833be709Roozbeh Pournader            minikinPaint, resolvedTypeface->fFontCollection, advances, nullptr /* extent */,
720aa07a712984a655215f20e664915b67833be709Roozbeh Pournader            nullptr /* overhangs */);
73a3024bd7026deb777556dd75dd34a719ea1c2b39Keisuke Kuroyanagi}
74a3024bd7026deb777556dd75dd34a719ea1c2b39Keisuke Kuroyanagi
75318ca04079bd6242cb6186d9005b9caeee22e845Seigo Nonakabool MinikinUtils::hasVariationSelector(const Typeface* typeface, uint32_t codepoint, uint32_t vs) {
76bad99183916ba2bac6659efc8a28273e344ba511sergeyv    const Typeface* resolvedFace = Typeface::resolveDefault(typeface);
77bb1a96647a82df5a134bf631fc9db342e7ef61deSeigo Nonaka    return resolvedFace->fFontCollection->hasVariationSelector(codepoint, vs);
78bb1a96647a82df5a134bf631fc9db342e7ef61deSeigo Nonaka}
79bb1a96647a82df5a134bf631fc9db342e7ef61deSeigo Nonaka
80ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonakafloat MinikinUtils::xOffsetForTextAlign(Paint* paint, const minikin::Layout& layout) {
81f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    switch (paint->getTextAlign()) {
826ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod        case Paint::kCenter_Align:
83f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            return layout.getAdvance() * -0.5f;
84f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            break;
856ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod        case Paint::kRight_Align:
86f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            return -layout.getAdvance();
87f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            break;
88f2114d5646194100242206b267ddd6e7194b7da9Raph Levien        default:
89f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            break;
90f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    }
91f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    return 0;
92f2114d5646194100242206b267ddd6e7194b7da9Raph Levien}
93f2114d5646194100242206b267ddd6e7194b7da9Raph Levien
94ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonakafloat MinikinUtils::hOffsetForTextAlign(Paint* paint, const minikin::Layout& layout,
95ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka        const SkPath& path) {
969d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien    float align = 0;
979d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien    switch (paint->getTextAlign()) {
986ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod        case Paint::kCenter_Align:
999d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien            align = -0.5f;
1009d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien            break;
1016ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod        case Paint::kRight_Align:
1029d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien            align = -1;
1039d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien            break;
1049d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien        default:
1059d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien            return 0;
1069d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien    }
1079d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien    SkPathMeasure measure(path, false);
1089d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien    return align * (layout.getAdvance() - measure.getLength());
1099d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien}
1109d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien
111f2114d5646194100242206b267ddd6e7194b7da9Raph Levien}
112