Raster packed (#5795)
* raster: use hb_packed_t for unaligned BGRA32 access
* algs: support encapsulated hb_packed_t and fix raster callsites
diff --git a/src/hb-algs.hh b/src/hb-algs.hh
index 0a7bdfc..c580496 100644
--- a/src/hb-algs.hh
+++ b/src/hb-algs.hh
@@ -89,7 +89,16 @@
{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
template <typename Type>
-struct __attribute__((packed)) hb_packed_t { Type v; };
+struct __attribute__((packed)) hb_packed_t
+{
+ hb_packed_t () = default;
+ constexpr hb_packed_t (Type V) : v (V) {}
+ operator Type () const { return v; }
+ hb_packed_t & operator = (Type V) { v = V; return *this; }
+
+ private:
+ Type v;
+};
#ifndef HB_FAST_NUM_ACCESS
@@ -134,9 +143,9 @@
#if HB_FAST_NUM_ACCESS
{
if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
- ((hb_packed_t<uint16_t> *) v)->v = V;
+ *((hb_packed_t<uint16_t> *) v) = V;
else
- ((hb_packed_t<uint16_t> *) v)->v = __builtin_bswap16 (V);
+ *((hb_packed_t<uint16_t> *) v) = __builtin_bswap16 (V);
}
#else
: v {BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V ) & 0xFF),
@@ -147,9 +156,9 @@
{
#if HB_FAST_NUM_ACCESS
return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ?
- ((const hb_packed_t<uint16_t> *) v)->v
+ (uint16_t) *((const hb_packed_t<uint16_t> *) v)
:
- __builtin_bswap16 (((const hb_packed_t<uint16_t> *) v)->v)
+ __builtin_bswap16 ((uint16_t) *((const hb_packed_t<uint16_t> *) v))
;
#else
return (BE ? (v[0] << 8) : (v[0] ))
@@ -186,9 +195,9 @@
#if HB_FAST_NUM_ACCESS
{
if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
- ((hb_packed_t<uint32_t> *) v)->v = V;
+ *((hb_packed_t<uint32_t> *) v) = V;
else
- ((hb_packed_t<uint32_t> *) v)->v = __builtin_bswap32 (V);
+ *((hb_packed_t<uint32_t> *) v) = __builtin_bswap32 (V);
}
#else
: v {BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V ) & 0xFF),
@@ -200,9 +209,9 @@
constexpr operator Type () const {
#if HB_FAST_NUM_ACCESS
return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ?
- ((const hb_packed_t<uint32_t> *) v)->v
+ (uint32_t) *((const hb_packed_t<uint32_t> *) v)
:
- __builtin_bswap32 (((const hb_packed_t<uint32_t> *) v)->v)
+ __builtin_bswap32 ((uint32_t) *((const hb_packed_t<uint32_t> *) v))
;
#else
return (BE ? (v[0] << 24) : (v[0] ))
@@ -226,9 +235,9 @@
#if HB_FAST_NUM_ACCESS
{
if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
- ((hb_packed_t<uint64_t> *) v)->v = V;
+ *((hb_packed_t<uint64_t> *) v) = V;
else
- ((hb_packed_t<uint64_t> *) v)->v = __builtin_bswap64 (V);
+ *((hb_packed_t<uint64_t> *) v) = __builtin_bswap64 (V);
}
#else
: v {BE ? uint8_t ((V >> 56) & 0xFF) : uint8_t ((V ) & 0xFF),
@@ -244,9 +253,9 @@
constexpr operator Type () const {
#if HB_FAST_NUM_ACCESS
return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ?
- ((const hb_packed_t<uint64_t> *) v)->v
+ (uint64_t) *((const hb_packed_t<uint64_t> *) v)
:
- __builtin_bswap64 (((const hb_packed_t<uint64_t> *) v)->v)
+ __builtin_bswap64 ((uint64_t) *((const hb_packed_t<uint64_t> *) v))
;
#else
return (BE ? (uint64_t (v[0]) << 56) : (uint64_t (v[0]) ))
@@ -276,12 +285,12 @@
{
#if HB_FAST_NUM_ACCESS
{
- if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
- {
- ((hb_packed_t<Type> *) v)->v = V;
- return;
- }
- }
+ if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
+ {
+ *((hb_packed_t<Type> *) v) = V;
+ return;
+ }
+ }
#endif
union {
@@ -289,7 +298,7 @@
hb_packed_t<IntType> i;
} u = {{V}};
- const HBInt<BE, IntType> I = u.i.v;
+ const HBInt<BE, IntType> I = (IntType) u.i;
for (unsigned i = 0; i < Bytes; i++)
v[i] = I.v[i];
}
@@ -297,10 +306,10 @@
/* c++14 constexpr */ operator Type () const
{
#if HB_FAST_NUM_ACCESS
- {
- if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
- return ((const hb_packed_t<Type> *) v)->v;
- }
+ {
+ if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
+ return (Type) *((const hb_packed_t<Type> *) v);
+ }
#endif
HBInt<BE, IntType> I;
@@ -312,7 +321,7 @@
hb_packed_t<Type> f;
} u = {{I}};
- return u.f.v;
+ return (Type) u.f;
}
private: uint8_t v[Bytes];
};
diff --git a/src/hb-raster-image.cc b/src/hb-raster-image.cc
index aaff8c7..77c6d2b 100644
--- a/src/hb-raster-image.cc
+++ b/src/hb-raster-image.cc
@@ -396,10 +396,10 @@
for (unsigned y = 0; y < h; y++)
{
- uint32_t *dp = reinterpret_cast<uint32_t *> (buffer.arrayZ + y * stride);
- const uint32_t *sp = reinterpret_cast<const uint32_t *> (src->buffer.arrayZ + y * stride);
+ hb_packed_t<uint32_t> *dp = (hb_packed_t<uint32_t> *) (buffer.arrayZ + y * stride);
+ const hb_packed_t<uint32_t> *sp = (const hb_packed_t<uint32_t> *) (src->buffer.arrayZ + y * stride);
for (unsigned x = 0; x < w; x++)
- dp[x] = composite_pixel (sp[x], dp[x], mode);
+ dp[x] = hb_packed_t<uint32_t> (composite_pixel ((uint32_t) sp[x], (uint32_t) dp[x], mode));
}
}
diff --git a/src/hb-raster-paint.cc b/src/hb-raster-paint.cc
index b9537f5..13d1a41 100644
--- a/src/hb-raster-paint.cc
+++ b/src/hb-raster-paint.cc
@@ -563,7 +563,7 @@
{
for (unsigned y = clip.min_y; y < clip.max_y; y++)
{
- uint32_t *__restrict row = reinterpret_cast<uint32_t *> (surf->buffer.arrayZ + y * stride);
+ hb_packed_t<uint32_t> *__restrict row = (hb_packed_t<uint32_t> *) (surf->buffer.arrayZ + y * stride);
const uint8_t *__restrict clip_row = clip.alpha.arrayZ + y * clip.stride;
for (unsigned x = clip.min_x; x < clip.max_x; x++)
{
@@ -572,14 +572,14 @@
if (clip_alpha == 255)
{
if (premul_a == 255)
- row[x] = premul;
+ row[x] = hb_packed_t<uint32_t> (premul);
else
- row[x] = hb_raster_src_over (premul, row[x]);
+ row[x] = hb_packed_t<uint32_t> (hb_raster_src_over (premul, (uint32_t) row[x]));
}
else
{
uint32_t src = hb_raster_alpha_mul (premul, clip_alpha);
- row[x] = hb_raster_src_over (src, row[x]);
+ row[x] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[x]));
}
}
}
@@ -588,9 +588,9 @@
{
for (unsigned y = clip.min_y; y < clip.max_y; y++)
{
- uint32_t *row = reinterpret_cast<uint32_t *> (surf->buffer.arrayZ + y * stride);
+ hb_packed_t<uint32_t> *row = (hb_packed_t<uint32_t> *) (surf->buffer.arrayZ + y * stride);
for (unsigned x = clip.min_x; x < clip.max_x; x++)
- row[x] = hb_raster_src_over (premul, row[x]);
+ row[x] = hb_packed_t<uint32_t> (hb_raster_src_over (premul, (uint32_t) row[x]));
}
}
}
@@ -653,6 +653,7 @@
float inv_y0 = (t.yx * t.x0 - t.xx * t.y0) * inv_det;
unsigned surf_stride = surf->extents.stride;
+ const hb_packed_t<uint32_t> *src_data = (const hb_packed_t<uint32_t> *) data;
int ox = surf->extents.x_origin;
int oy = surf->extents.y_origin;
@@ -666,7 +667,7 @@
{
for (unsigned py = clip.min_y; py < clip.max_y; py++)
{
- uint32_t *row = reinterpret_cast<uint32_t *> (surf->buffer.arrayZ + py * surf_stride);
+ hb_packed_t<uint32_t> *row = (hb_packed_t<uint32_t> *) (surf->buffer.arrayZ + py * surf_stride);
float gx = inv_xx * (float) ((int) clip.min_x + ox) + inv_xy * (float) ((int) py + oy) + inv_x0;
float gy = inv_yx * (float) ((int) clip.min_x + ox) + inv_yy * (float) ((int) py + oy) + inv_y0;
for (unsigned px = clip.min_x; px < clip.max_x; px++)
@@ -682,8 +683,8 @@
continue;
}
- uint32_t src_px = reinterpret_cast<const uint32_t *> (data)[iy * width + ix];
- row[px] = hb_raster_src_over (src_px, row[px]);
+ uint32_t src_px = ((uint32_t) src_data[iy * width + ix]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src_px, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -693,7 +694,7 @@
{
for (unsigned py = clip.min_y; py < clip.max_y; py++)
{
- uint32_t *row = reinterpret_cast<uint32_t *> (surf->buffer.arrayZ + py * surf_stride);
+ hb_packed_t<uint32_t> *row = (hb_packed_t<uint32_t> *) (surf->buffer.arrayZ + py * surf_stride);
const uint8_t *clip_row = clip.alpha.arrayZ + py * clip.stride;
float gx = inv_xx * (float) ((int) clip.min_x + ox) + inv_xy * (float) ((int) py + oy) + inv_x0;
float gy = inv_yx * (float) ((int) clip.min_x + ox) + inv_yy * (float) ((int) py + oy) + inv_y0;
@@ -718,9 +719,9 @@
continue;
}
- uint32_t src_px = reinterpret_cast<const uint32_t *> (data)[iy * width + ix];
+ uint32_t src_px = ((uint32_t) src_data[iy * width + ix]);
src_px = hb_raster_alpha_mul (src_px, clip_alpha);
- row[px] = hb_raster_src_over (src_px, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src_px, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -999,7 +1000,7 @@
{
for (unsigned py = clip.min_y; py < clip.max_y; py++)
{
- uint32_t *row = reinterpret_cast<uint32_t *> (surf->buffer.arrayZ + py * stride);
+ hb_packed_t<uint32_t> *row = (hb_packed_t<uint32_t> *) (surf->buffer.arrayZ + py * stride);
float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0;
float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0;
if (use_lut)
@@ -1008,7 +1009,7 @@
{
float proj_t = ((gx - gx0) * dx + (gy - gy0) * dy) * inv_denom;
uint32_t src = lookup_gradient_lut (lut, proj_t, extend);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1019,7 +1020,7 @@
{
float proj_t = ((gx - gx0) * dx + (gy - gy0) * dy) * inv_denom;
uint32_t src = evaluate_color_line (stops, len, proj_t, extend);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1030,7 +1031,7 @@
{
for (unsigned py = clip.min_y; py < clip.max_y; py++)
{
- uint32_t *row = reinterpret_cast<uint32_t *> (surf->buffer.arrayZ + py * stride);
+ hb_packed_t<uint32_t> *row = (hb_packed_t<uint32_t> *) (surf->buffer.arrayZ + py * stride);
const uint8_t *clip_row = clip.alpha.arrayZ + py * clip.stride;
float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0;
float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0;
@@ -1048,7 +1049,7 @@
float proj_t = ((gx - gx0) * dx + (gy - gy0) * dy) * inv_denom;
uint32_t src = lookup_gradient_lut (lut, proj_t, extend);
src = hb_raster_alpha_mul (src, clip_alpha);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1067,7 +1068,7 @@
float proj_t = ((gx - gx0) * dx + (gy - gy0) * dy) * inv_denom;
uint32_t src = evaluate_color_line (stops, len, proj_t, extend);
src = hb_raster_alpha_mul (src, clip_alpha);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1156,7 +1157,7 @@
{
for (unsigned py = clip.min_y; py < clip.max_y; py++)
{
- uint32_t *row = reinterpret_cast<uint32_t *> (surf->buffer.arrayZ + py * stride);
+ hb_packed_t<uint32_t> *row = (hb_packed_t<uint32_t> *) (surf->buffer.arrayZ + py * stride);
float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0;
float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0;
if (use_lut)
@@ -1200,7 +1201,7 @@
}
uint32_t src = lookup_gradient_lut (lut, grad_t, extend);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1240,7 +1241,7 @@
}
uint32_t src = evaluate_color_line (stops, len, grad_t, extend);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1251,7 +1252,7 @@
{
for (unsigned py = clip.min_y; py < clip.max_y; py++)
{
- uint32_t *row = reinterpret_cast<uint32_t *> (surf->buffer.arrayZ + py * stride);
+ hb_packed_t<uint32_t> *row = (hb_packed_t<uint32_t> *) (surf->buffer.arrayZ + py * stride);
const uint8_t *clip_row = clip.alpha.arrayZ + py * clip.stride;
float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0;
float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0;
@@ -1298,7 +1299,7 @@
uint32_t src = lookup_gradient_lut (lut, grad_t, extend);
src = hb_raster_alpha_mul (src, clip_alpha);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1346,7 +1347,7 @@
uint32_t src = evaluate_color_line (stops, len, grad_t, extend);
src = hb_raster_alpha_mul (src, clip_alpha);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1422,7 +1423,7 @@
{
for (unsigned py = clip.min_y; py < clip.max_y; py++)
{
- uint32_t *row = reinterpret_cast<uint32_t *> (surf->buffer.arrayZ + py * stride);
+ hb_packed_t<uint32_t> *row = (hb_packed_t<uint32_t> *) (surf->buffer.arrayZ + py * stride);
float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0;
float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0;
if (use_lut)
@@ -1433,7 +1434,7 @@
if (angle < 0) angle += (float) HB_2_PI;
float grad_t = (angle - a0) * inv_angle_range;
uint32_t src = lookup_gradient_lut (lut, grad_t, extend);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1446,7 +1447,7 @@
if (angle < 0) angle += (float) HB_2_PI;
float grad_t = (angle - a0) * inv_angle_range;
uint32_t src = evaluate_color_line (stops, len, grad_t, extend);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1457,7 +1458,7 @@
{
for (unsigned py = clip.min_y; py < clip.max_y; py++)
{
- uint32_t *row = reinterpret_cast<uint32_t *> (surf->buffer.arrayZ + py * stride);
+ hb_packed_t<uint32_t> *row = (hb_packed_t<uint32_t> *) (surf->buffer.arrayZ + py * stride);
const uint8_t *clip_row = clip.alpha.arrayZ + py * clip.stride;
float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0;
float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0;
@@ -1477,7 +1478,7 @@
float grad_t = (angle - a0) * inv_angle_range;
uint32_t src = lookup_gradient_lut (lut, grad_t, extend);
src = hb_raster_alpha_mul (src, clip_alpha);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}
@@ -1498,7 +1499,7 @@
float grad_t = (angle - a0) * inv_angle_range;
uint32_t src = evaluate_color_line (stops, len, grad_t, extend);
src = hb_raster_alpha_mul (src, clip_alpha);
- row[px] = hb_raster_src_over (src, row[px]);
+ row[px] = hb_packed_t<uint32_t> (hb_raster_src_over (src, (uint32_t) row[px]));
gx += inv_xx;
gy += inv_yx;
}