Flutter Engine
The Flutter Engine
orientation.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm/gm.h"
12#include "include/core/SkFont.h"
16#include "include/core/SkSize.h"
19#include "tools/DecodeUtils.h"
20#include "tools/EncodeUtils.h"
21#include "tools/Resources.h"
22#include "tools/ToolUtils.h"
24
25static constexpr int kImgW = 100;
26static constexpr int kImgH = 80;
27
28/**
29 This function was used to create the images used by these test. It saves them as PNGs (so they
30 are lossless). Then the following bash script was used to create the oriented JPGs with
31 imagemagick and exiftool:
32#!/bin/bash
33
34for s in 444 422 420 440 411 410; do
35 for i in {1..8}; do
36 magick convert $i.png -sampling-factor ${s:0:1}:${s:1:1}:${s:2:1} $i\_$s.jpg;
37 exiftool -orientation=$i -n -m -overwrite_original $i\_$s.jpg;
38 done
39done
40
41 */
42static void make_images() {
43 for (int i = 1; i <= 8; ++i) {
45 SkEncodedOrigin origin = static_cast<SkEncodedOrigin>(i);
46 // We apply the inverse transformation to the PNG we generate, convert the PNG to a
47 // a JPEG using magick, then modify the JPEG's tag using exiftool (without modifying the
48 // stored JPEG data).
49 if (origin >= kLeftTop_SkEncodedOrigin) {
50 // The last four SkEncodedOrigin values involve 90 degree rotations
51 using std::swap;
52 swap(size.fWidth, size.fHeight);
53 }
54 using std::swap;
55 auto surf = SkSurfaces::Raster(
57 auto* canvas = surf->getCanvas();
59 SkAssertResult(m.invert(&m));
60 canvas->concat(m);
61 canvas->clear(SK_ColorBLACK);
63 paint.setColor(SK_ColorRED);
64 SkScalar midX = kImgW / 2.f;
65 SkScalar midY = kImgH / 2.f;
66 SkScalar w = midX - 1;
67 SkScalar h = midY - 1;
68 canvas->drawRect(SkRect::MakeXYWH(1, 1, w, h), paint);
69 paint.setColor(SK_ColorBLUE);
70 canvas->drawRect(SkRect::MakeXYWH(midX, 1, w, h), paint);
71 paint.setColor(SK_ColorGREEN);
72 canvas->drawRect(SkRect::MakeXYWH(1, midY, w, h), paint);
73 paint.setColor(SK_ColorYELLOW);
74 canvas->drawRect(SkRect::MakeXYWH(midX, midY, w, h), paint);
76
77 SkPaint blurPaint;
79 blurPaint.setColor(SK_ColorBLACK);
80 paint.setColor(SK_ColorWHITE);
81
82 auto drawLabel = [&](const char* string, SkScalar x, SkScalar y) {
83 canvas->save();
84 canvas->translate(1, 1);
85 canvas->drawString(string, x, y, font, blurPaint);
86 canvas->restore();
87 canvas->drawString(string, x, y, font, paint);
88 };
89
90 auto measure = [&font](const char* text) {
92 font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
93 return bounds;
94 };
95
96 static constexpr SkScalar kPad = 3.f;
98
99 bounds = measure("top");
100 drawLabel("top", midX - bounds.centerX(), -bounds.top() + kPad);
101
102 bounds = measure("bottom");
103 drawLabel("bottom", midX - bounds.centerX(), kImgH - kPad - bounds.bottom());
104
105 // It looks weird if "left" and "right" and the number at the center aren't vertically
106 // aligned.
107 SkScalar baseY = midY - measure("leftright").centerY();
108 bounds = measure("left");
109 drawLabel("left", kPad - bounds.left(), baseY);
110
111 bounds = measure("right");
112 drawLabel("right", kImgW - kPad - bounds.right(), baseY);
113
114 SkString num = SkStringPrintf("%d", i);
115 bounds = measure(num.c_str());
116 drawLabel(num.c_str(), midX - bounds.centerX(), baseY);
117 num.append(".png");
118 SkPixmap pm;
119 surf->makeImageSnapshot()->peekPixels(&pm);
121 }
122}
123
124// This gm draws 8 images that are mostly the same when respecting the
125// EXIF orientation tag. Each one has four quadrants (red, blue, green,
126// yellow), and labels on the left, top, right and bottom. The only
127// visual difference is a number in the middle corresponding to the
128// EXIF tag for that image's jpg file.
129static void draw(SkCanvas* canvas, const char* suffix) {
130 // Avoid unused function warning.
131 if ((false)) {
132 make_images();
133 }
134 canvas->save();
135 for (char i = '1'; i <= '8'; i++) {
136 SkString path = SkStringPrintf("images/orientation/%c%s.jpg", i, suffix);
138 if (!image) {
139 continue;
140 }
141 canvas->drawImage(image, 0, 0);
142 if ('4' == i) {
143 canvas->restore();
144 canvas->translate(0, image->height());
145 } else {
146 canvas->translate(image->width(), 0);
147 }
148 }
149}
150
151#define MAKE_GM(subsample) DEF_SIMPLE_GM(orientation_##subsample, canvas, 4*kImgW, 2*kImgH) { \
152 draw(canvas, "_" #subsample); \
153}
154
155MAKE_GM(410)
156MAKE_GM(411)
157MAKE_GM(420)
158MAKE_GM(422)
159MAKE_GM(440)
160MAKE_GM(444)
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
@ kNormal_SkBlurStyle
fuzzy inside and outside
Definition: SkBlurTypes.h:12
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
constexpr SkColor SK_ColorYELLOW
Definition: SkColor.h:139
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
SkEncodedOrigin
@ kLeftTop_SkEncodedOrigin
static SkMatrix SkEncodedOriginToMatrix(SkEncodedOrigin origin, int w, int h)
@ kUTF8
uses bytes to represent UTF-8 or ASCII
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
constexpr int kPad
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
int save()
Definition: SkCanvas.cpp:447
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
Definition: SkFont.h:35
int width() const
Definition: SkImage.h:285
int height() const
Definition: SkImage.h:291
static sk_sp< SkMaskFilter > MakeBlur(SkBlurStyle style, SkScalar sigma, bool respectCTM=true)
void setColor(SkColor color)
Definition: SkPaint.cpp:119
void setMaskFilter(sk_sp< SkMaskFilter > maskFilter)
void append(const char text[])
Definition: SkString.h:203
const char * c_str() const
Definition: SkString.h:133
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
std::u16string text
double y
double x
Optional< SkRect > bounds
Definition: SkRecords.h:189
sk_sp< const SkImage > image
Definition: SkRecords.h:269
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
sk_sp< SkTypeface > DefaultPortableTypeface()
bool EncodeImageToPngFile(const char *path, const SkBitmap &src)
Definition: EncodeUtils.cpp:60
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition: DecodeUtils.h:25
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
font
Font Metadata and Metrics.
static void draw(SkCanvas *canvas, const char *suffix)
static constexpr int kImgH
Definition: orientation.cpp:26
static constexpr int kImgW
Definition: orientation.cpp:25
#define MAKE_GM(subsample)
static void make_images()
Definition: orientation.cpp:42
SkScalar w
SkScalar h
Definition: SkSize.h:16
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659