17de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett/*
27de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett * Copyright (C) 2016 The Android Open Source Project
37de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett *
47de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett * Licensed under the Apache License, Version 2.0 (the "License");
57de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett * you may not use this file except in compliance with the License.
67de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett * You may obtain a copy of the License at
77de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett *
87de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett *      http://www.apache.org/licenses/LICENSE-2.0
97de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett *
107de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett * Unless required by applicable law or agreed to in writing, software
117de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett * distributed under the License is distributed on an "AS IS" BASIS,
127de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett * See the License for the specific language governing permissions and
147de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett * limitations under the License.
157de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett */
167de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett
17021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#pragma once
18021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
197de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarettnamespace android {
207de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarettnamespace NinePatchUtils {
217de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett
227de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarettstatic inline void SetLatticeDivs(SkCanvas::Lattice* lattice, const Res_png_9patch& chunk,
237de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett        int width, int height) {
247de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett    lattice->fXCount = chunk.numXDivs;
257de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett    lattice->fYCount = chunk.numYDivs;
267de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett    lattice->fXDivs = chunk.getXDivs();
277de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett    lattice->fYDivs = chunk.getYDivs();
287de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett
297de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett    // We'll often see ninepatches where the last div is equal to the width or height.
307de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett    // This doesn't provide any additional information and is not supported by Skia.
317de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett    if (lattice->fXCount > 0 && width == lattice->fXDivs[lattice->fXCount - 1]) {
327de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett        lattice->fXCount--;
337de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett    }
347de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett    if (lattice->fYCount > 0 && height == lattice->fYDivs[lattice->fYCount - 1]) {
357de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett        lattice->fYCount--;
367de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett    }
377de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett}
387de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett
39021693b967a2c5556dddd183eb0247df4079e1adStan Ilievstatic inline int NumDistinctRects(const SkCanvas::Lattice& lattice) {
40021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    int xRects;
41021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    if (lattice.fXCount > 0) {
42021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        xRects = (0 == lattice.fXDivs[0]) ? lattice.fXCount : lattice.fXCount + 1;
43021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    } else {
44021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        xRects = 1;
45021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    }
46021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
47021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    int yRects;
48021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    if (lattice.fYCount > 0) {
49021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        yRects = (0 == lattice.fYDivs[0]) ? lattice.fYCount : lattice.fYCount + 1;
50021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    } else {
51021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        yRects = 1;
52021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    }
53021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    return xRects * yRects;
54021693b967a2c5556dddd183eb0247df4079e1adStan Iliev}
55021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
56021693b967a2c5556dddd183eb0247df4079e1adStan Ilievstatic inline void SetLatticeFlags(SkCanvas::Lattice* lattice, SkCanvas::Lattice::Flags* flags,
57021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        int numFlags, const Res_png_9patch& chunk) {
58021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    lattice->fFlags = flags;
59021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    sk_bzero(flags, numFlags * sizeof(SkCanvas::Lattice::Flags));
60021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
61021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    bool needPadRow = lattice->fYCount > 0 && 0 == lattice->fYDivs[0];
62021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    bool needPadCol = lattice->fXCount > 0 && 0 == lattice->fXDivs[0];
63021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
64021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    int yCount = lattice->fYCount;
65021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    if (needPadRow) {
66021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        // Skip flags for the degenerate first row of rects.
67021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        flags += lattice->fXCount + 1;
68021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        yCount--;
69021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    }
70021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
71021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    int i = 0;
72021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    bool setFlags = false;
73021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    for (int y = 0; y < yCount + 1; y++) {
74021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        for (int x = 0; x < lattice->fXCount + 1; x++) {
75021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            if (0 == x && needPadCol) {
76021693b967a2c5556dddd183eb0247df4079e1adStan Iliev                // First rect of each column is degenerate, skip the flag.
77021693b967a2c5556dddd183eb0247df4079e1adStan Iliev                flags++;
78021693b967a2c5556dddd183eb0247df4079e1adStan Iliev                continue;
79021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            }
80021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
81021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            if (0 == chunk.getColors()[i++]) {
82021693b967a2c5556dddd183eb0247df4079e1adStan Iliev                *flags = SkCanvas::Lattice::kTransparent_Flags;
83021693b967a2c5556dddd183eb0247df4079e1adStan Iliev                setFlags = true;
84021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            }
85021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
86021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            flags++;
87021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
88021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    }
89021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
90021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    if (!setFlags) {
91021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        lattice->fFlags = nullptr;
92021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    }
93021693b967a2c5556dddd183eb0247df4079e1adStan Iliev}
94021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
957de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett}; // namespace NinePatchUtils
967de73858975fc4dbccfa1c188f6d1a12d39ce2c5Matt Sarett}; // namespace android
97