inline void packet(char* buff, size_t* buff_n, bool pack) { pack_u8(&id, buff, buff_n, pack); pack_u8(&client_id, buff, buff_n, pack); pack_color(&color, buff, buff_n, pack); pack_string(username, PLAYER_NAME_MAX_LENGTH+1, buff, buff_n, pack); }
void SkGradientShaderBase:: GradientShaderBase4fContext::addMirrorIntervals(const SkGradientShaderBase& shader, const Sk4f& componentScale, bool reverse) { const IntervalIterator iter(shader.fOrigColors, shader.fOrigPos, shader.fColorCount, reverse); iter.iterate([this, &componentScale] (SkColor c0, SkColor c1, SkScalar p0, SkScalar p1) { SkASSERT(fIntervals.empty() || fIntervals.back().fP1 == 2 - p0); fIntervals.emplace_back(pack_color(c0, fColorsArePremul), 2 - p0, pack_color(c1, fColorsArePremul), 2 - p1, componentScale); }); }
void SkGradientShaderBase:: GradientShaderBase4fContext::buildIntervals(const SkGradientShaderBase& shader, const ContextRec& rec, bool reverse) { // The main job here is to build a specialized interval list: a different // representation of the color stops data, optimized for efficient scan line // access during shading. // // [{P0,C0} , {P1,C1}) [{P1,C2} , {P2,c3}) ... [{Pn,C2n} , {Pn+1,C2n+1}) // // The list may be inverted when requested (such that e.g. points are sorted // in increasing x order when dx < 0). // // Note: the current representation duplicates pos data; we could refactor to // avoid this if interval storage size becomes a concern. // // Aside from reordering, we also perform two more pre-processing steps at // this stage: // // 1) scale the color components depending on paint alpha and the requested // interpolation space (note: the interval color storage is SkPM4f, but // that doesn't necessarily mean the colors are premultiplied; that // property is tracked in fColorsArePremul) // // 2) inject synthetic intervals to support tiling. // // * for kRepeat, no extra intervals are needed - the iterator just // wraps around at the end: // // ->[P0,P1)->..[Pn-1,Pn)-> // // * for kClamp, we add two "infinite" intervals before/after: // // [-/+inf , P0)->[P0 , P1)->..[Pn-1 , Pn)->[Pn , +/-inf) // // (the iterator should never run off the end in this mode) // // * for kMirror, we extend the range to [0..2] and add a flipped // interval series - then the iterator operates just as in the // kRepeat case: // // ->[P0,P1)->..[Pn-1,Pn)->[2 - Pn,2 - Pn-1)->..[2 - P1,2 - P0)-> // // TODO: investigate collapsing intervals << 1px. SkASSERT(shader.fColorCount > 0); SkASSERT(shader.fOrigColors); const float paintAlpha = rec.fPaint->getAlpha() * (1.0f / 255); const Sk4f componentScale = fColorsArePremul ? Sk4f(paintAlpha) : Sk4f(1.0f, 1.0f, 1.0f, paintAlpha); const int first_index = reverse ? shader.fColorCount - 1 : 0; const int last_index = shader.fColorCount - 1 - first_index; const SkScalar first_pos = reverse ? SK_Scalar1 : 0; const SkScalar last_pos = SK_Scalar1 - first_pos; if (shader.fTileMode == SkShader::kClamp_TileMode) { // synthetic edge interval: -/+inf .. P0 const SkPMColor clamp_color = pack_color(shader.fOrigColors[first_index], fColorsArePremul); const SkScalar clamp_pos = reverse ? SK_ScalarMax : SK_ScalarMin; fIntervals.emplace_back(clamp_color, clamp_pos, clamp_color, first_pos, componentScale); } else if (shader.fTileMode == SkShader::kMirror_TileMode && reverse) { // synthetic mirror intervals injected before main intervals: (2 .. 1] addMirrorIntervals(shader, componentScale, false); } const IntervalIterator iter(shader.fOrigColors, shader.fOrigPos, shader.fColorCount, reverse); iter.iterate([this, &componentScale] (SkColor c0, SkColor c1, SkScalar p0, SkScalar p1) { SkASSERT(fIntervals.empty() || fIntervals.back().fP1 == p0); fIntervals.emplace_back(pack_color(c0, fColorsArePremul), p0, pack_color(c1, fColorsArePremul), p1, componentScale); }); if (shader.fTileMode == SkShader::kClamp_TileMode) { // synthetic edge interval: Pn .. +/-inf const SkPMColor clamp_color = pack_color(shader.fOrigColors[last_index], fColorsArePremul); const SkScalar clamp_pos = reverse ? SK_ScalarMin : SK_ScalarMax; fIntervals.emplace_back(clamp_color, last_pos, clamp_color, clamp_pos, componentScale); } else if (shader.fTileMode == SkShader::kMirror_TileMode && !reverse) { // synthetic mirror intervals injected after main intervals: [1 .. 2) addMirrorIntervals(shader, componentScale, true); } }
inline void packet(char* buff, size_t* buff_n, bool pack) { pack_u8(&agent_id, buff, buff_n, pack); pack_color(&color, buff, buff_n, pack); }
void Sk4fGradientIntervalBuffer::init(const SkGradientShaderBase& shader, SkColorSpace* dstCS, SkTileMode tileMode, bool premulColors, SkScalar alpha, bool reverse) { // The main job here is to build a specialized interval list: a different // representation of the color stops data, optimized for efficient scan line // access during shading. // // [{P0,C0} , {P1,C1}) [{P1,C2} , {P2,c3}) ... [{Pn,C2n} , {Pn+1,C2n+1}) // // The list may be inverted when requested (such that e.g. points are sorted // in increasing x order when dx < 0). // // Note: the current representation duplicates pos data; we could refactor to // avoid this if interval storage size becomes a concern. // // Aside from reordering, we also perform two more pre-processing steps at // this stage: // // 1) scale the color components depending on paint alpha and the requested // interpolation space (note: the interval color storage is SkPMColor4f, but // that doesn't necessarily mean the colors are premultiplied; that // property is tracked in fColorsArePremul) // // 2) inject synthetic intervals to support tiling. // // * for kRepeat, no extra intervals are needed - the iterator just // wraps around at the end: // // ->[P0,P1)->..[Pn-1,Pn)-> // // * for kClamp, we add two "infinite" intervals before/after: // // [-/+inf , P0)->[P0 , P1)->..[Pn-1 , Pn)->[Pn , +/-inf) // // (the iterator should never run off the end in this mode) // // * for kMirror, we extend the range to [0..2] and add a flipped // interval series - then the iterator operates just as in the // kRepeat case: // // ->[P0,P1)->..[Pn-1,Pn)->[2 - Pn,2 - Pn-1)->..[2 - P1,2 - P0)-> // // TODO: investigate collapsing intervals << 1px. const auto count = shader.fColorCount; SkASSERT(count > 0); fIntervals.reset(); const Sk4f componentScale = premulColors ? Sk4f(alpha) : Sk4f(1.0f, 1.0f, 1.0f, alpha); const int first_index = reverse ? count - 1 : 0; const int last_index = count - 1 - first_index; const SkScalar first_pos = reverse ? SK_Scalar1 : 0; const SkScalar last_pos = SK_Scalar1 - first_pos; // Transform all of the colors to destination color space SkColor4fXformer xformedColors(shader.fOrigColors4f, count, shader.fColorSpace.get(), dstCS); if (tileMode == SkTileMode::kClamp) { // synthetic edge interval: -/+inf .. P0 const Sk4f clamp_color = pack_color(xformedColors.fColors[first_index], premulColors, componentScale); const SkScalar clamp_pos = reverse ? SK_ScalarInfinity : SK_ScalarNegativeInfinity; fIntervals.emplace_back(clamp_color, clamp_pos, clamp_color, first_pos); } else if (tileMode == SkTileMode::kMirror && reverse) { // synthetic mirror intervals injected before main intervals: (2 .. 1] addMirrorIntervals(shader, xformedColors.fColors, componentScale, premulColors, false, &fIntervals); } const IntervalIterator iter(shader, reverse); iter.iterate(xformedColors.fColors, [&] (const SkColor4f& c0, const SkColor4f& c1, SkScalar t0, SkScalar t1) { SkASSERT(fIntervals.empty() || fIntervals.back().fT1 == t0); fIntervals.emplace_back(pack_color(c0, premulColors, componentScale), t0, pack_color(c1, premulColors, componentScale), t1); }); if (tileMode == SkTileMode::kClamp) { // synthetic edge interval: Pn .. +/-inf const Sk4f clamp_color = pack_color(xformedColors.fColors[last_index], premulColors, componentScale); const SkScalar clamp_pos = reverse ? SK_ScalarNegativeInfinity : SK_ScalarInfinity; fIntervals.emplace_back(clamp_color, last_pos, clamp_color, clamp_pos); } else if (tileMode == SkTileMode::kMirror && !reverse) { // synthetic mirror intervals injected after main intervals: [1 .. 2) addMirrorIntervals(shader, xformedColors.fColors, componentScale, premulColors, true, &fIntervals); } }