void cmsXYZ2LabEncoded(WORD XYZ[3], WORD Lab[3]) { Fixed32 X, Y, Z; double x, y, z, L, a, b; double fx, fy, fz; Fixed32 wL, wa, wb; X = (Fixed32) XYZ[0] << 1; Y = (Fixed32) XYZ[1] << 1; Z = (Fixed32) XYZ[2] << 1; if (X==0 && Y==0 && Z==0) { Lab[0] = 0; Lab[1] = Lab[2] = 0x8000; return; } // PCS is in D50 x = FIXED_TO_DOUBLE(X) / D50X; y = FIXED_TO_DOUBLE(Y) / D50Y; z = FIXED_TO_DOUBLE(Z) / D50Z; fx = f(x); fy = f(y); fz = f(z); L = 116.* fy - 16.; a = 500.*(fx - fy); b = 200.*(fy - fz); a += 128.; b += 128.; wL = (int) (L * 652.800 + .5); wa = (int) (a * 256.0 + .5); wb = (int) (b * 256.0 + .5); Lab[0] = Clamp_L(wL); Lab[1] = Clamp_ab(wa); Lab[2] = Clamp_ab(wb); }
double IOHIDParametricAcceleration::GetCurveParameter (CFDictionaryRef curve, CFStringRef key) { CFDictionaryRefWrap curveWrap (curve); CFNumberRefWrap value = (CFNumberRef)curveWrap[key]; if (value.Reference() == NULL) { return 0; } return FIXED_TO_DOUBLE((SInt64)value); }
static double XYZ2float(WORD v) { Fixed32 fix32; // From 1.15 to 15.16 fix32 = v << 1; // From fixed 15.16 to double return FIXED_TO_DOUBLE(fix32); }
idStr& idStr::operator+= ( const gfixed a ) { char text[ 20 ]; sprintf( text, "%f", FIXED_TO_DOUBLE(a) ); append( text ); return *this; }
idStr operator+ ( const idStr& a, const gfixed b ) { char text[ 20 ]; idStr result( a ); sprintf( text, "%f", FIXED_TO_DOUBLE(b) ); result.append( text ); return result; }
void R_InitSkyTexCoords( bfixed heightCloud ) { int i, s, t; bfixed radiusWorld = BFIXED(4096,0); double fradiusWorld = 4096.0; double fheightCloud = FIXED_TO_DOUBLE(heightCloud); float p; gfixed sRad, tRad; bvec3_t skyVec; bvec3_t v; float fskyvec[3]; // init zfar so MakeSkyVec works even though // a world hasn't been bounded backEnd.viewParms.zFar = BFIXED(1024,0); for ( i = 0; i < 6; i++ ) { for ( t = 0; t <= SKY_SUBDIVISIONS; t++ ) { for ( s = 0; s <= SKY_SUBDIVISIONS; s++ ) { // compute vector from view origin to sky side integral point MakeSkyVec( FIXED_INT32RATIO_G( s - HALF_SKY_SUBDIVISIONS, HALF_SKY_SUBDIVISIONS), FIXED_INT32RATIO_G( t - HALF_SKY_SUBDIVISIONS, HALF_SKY_SUBDIVISIONS), i, NULL, skyVec ); fskyvec[0]=FIXED_TO_FLOAT(skyVec[0]); fskyvec[1]=FIXED_TO_FLOAT(skyVec[1]); fskyvec[2]=FIXED_TO_FLOAT(skyVec[2]); // compute parametric value 'p' that intersects with cloud layer p = ( 1.0 / ( 2.0* ( fskyvec[0]*fskyvec[0] + fskyvec[1]*fskyvec[1] + fskyvec[2]*fskyvec[2] ) ) ) * ( -2.0* fskyvec[2] * fradiusWorld + 2.0* sqrt( SQR( fskyvec[2] ) * SQR( fradiusWorld ) + 2.0* SQR( fskyvec[0] ) * fradiusWorld * fheightCloud + SQR( fskyvec[0] ) * SQR( fheightCloud ) + 2.0* SQR( fskyvec[1] ) * fradiusWorld * fheightCloud + SQR( fskyvec[1] ) * SQR( fheightCloud ) + 2.0* SQR( fskyvec[2] ) * fradiusWorld * fheightCloud + SQR( fskyvec[2] ) * SQR( fheightCloud ) ) ); s_cloudTexP[i][t][s] = MAKE_GFIXED(p); // compute intersection point based on p FIXED_VEC3SCALE( skyVec, MAKE_BFIXED(p), v ); v[2] += radiusWorld; // compute vector from world origin to intersection point 'v' VectorNormalize( v ); sRad = MAKE_GFIXED(Q_acos( v[0] )); tRad = MAKE_GFIXED(Q_acos( v[1] )); s_cloudTexCoords[i][t][s][0] = sRad; s_cloudTexCoords[i][t][s][1] = tRad; } } } }
double ACCEL_TABLE::scale () const { return FIXED_TO_DOUBLE(scale<IOFixed>()); }
double ACCEL_TABLE_ENTRY::y (unsigned int index) const { return FIXED_TO_DOUBLE(y<IOFixed>(index)); }
double ACCEL_TABLE_ENTRY::acceleration<double> () const { return FIXED_TO_DOUBLE(acceleration<IOFixed>()); }
// paint the window void SceneXrender::Window::performPaint(int mask, QRegion region, WindowPaintData data) { setTransformedShape(QRegion()); // maybe nothing will be painted // check if there is something to paint bool opaque = isOpaque() && qFuzzyCompare(data.opacity(), 1.0); /* HACK: It seems this causes painting glitches, disable temporarily if (( mask & PAINT_WINDOW_OPAQUE ) ^ ( mask & PAINT_WINDOW_TRANSLUCENT )) { // We are only painting either opaque OR translucent windows, not both if ( mask & PAINT_WINDOW_OPAQUE && !opaque ) return; // Only painting opaque and window is translucent if ( mask & PAINT_WINDOW_TRANSLUCENT && opaque ) return; // Only painting translucent and window is opaque }*/ // Intersect the clip region with the rectangle the window occupies on the screen if (!(mask & (PAINT_WINDOW_TRANSFORMED | PAINT_SCREEN_TRANSFORMED))) region &= toplevel->visibleRect(); if (region.isEmpty()) return; XRenderWindowPixmap *pixmap = windowPixmap<XRenderWindowPixmap>(); if (!pixmap || !pixmap->isValid()) { return; } xcb_render_picture_t pic = pixmap->picture(); if (pic == XCB_RENDER_PICTURE_NONE) // The render format can be null for GL and/or Xv visuals return; toplevel->resetDamage(); // set picture filter if (options->isXrenderSmoothScale()) { // only when forced, it's slow if (mask & PAINT_WINDOW_TRANSFORMED) filter = ImageFilterGood; else if (mask & PAINT_SCREEN_TRANSFORMED) filter = ImageFilterGood; else filter = ImageFilterFast; } else filter = ImageFilterFast; // do required transformations const QRect wr = mapToScreen(mask, data, QRect(0, 0, width(), height())); QRect cr = QRect(toplevel->clientPos(), toplevel->clientSize()); // Client rect (in the window) qreal xscale = 1; qreal yscale = 1; bool scaled = false; Client *client = dynamic_cast<Client*>(toplevel); Deleted *deleted = dynamic_cast<Deleted*>(toplevel); const QRect decorationRect = toplevel->decorationRect(); if (((client && !client->noBorder()) || (deleted && !deleted->noBorder())) && true) { // decorated client transformed_shape = decorationRect; if (toplevel->shape()) { // "xeyes" + decoration transformed_shape -= cr; transformed_shape += shape(); } } else { transformed_shape = shape(); } if (toplevel->hasShadow()) transformed_shape |= toplevel->shadow()->shadowRegion(); xcb_render_transform_t xform = { DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1) }; static const xcb_render_transform_t identity = { DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1) }; if (mask & PAINT_WINDOW_TRANSFORMED) { xscale = data.xScale(); yscale = data.yScale(); } if (mask & PAINT_SCREEN_TRANSFORMED) { xscale *= screen_paint.xScale(); yscale *= screen_paint.yScale(); } if (!qFuzzyCompare(xscale, 1.0) || !qFuzzyCompare(yscale, 1.0)) { scaled = true; xform.matrix11 = DOUBLE_TO_FIXED(1.0 / xscale); xform.matrix22 = DOUBLE_TO_FIXED(1.0 / yscale); // transform the shape for clipping in paintTransformedScreen() QVector<QRect> rects = transformed_shape.rects(); for (int i = 0; i < rects.count(); ++i) { QRect& r = rects[ i ]; r.setRect(qRound(r.x() * xscale), qRound(r.y() * yscale), qRound(r.width() * xscale), qRound(r.height() * yscale)); } transformed_shape.setRects(rects.constData(), rects.count()); } transformed_shape.translate(mapToScreen(mask, data, QPoint(0, 0))); PaintClipper pcreg(region); // clip by the region to paint PaintClipper pc(transformed_shape); // clip by window's shape const bool wantShadow = m_shadow && !m_shadow->shadowRegion().isEmpty(); // In order to obtain a pixel perfect rescaling // we need to blit the window content togheter with // decorations in a temporary pixmap and scale // the temporary pixmap at the end. // We should do this only if there is scaling and // the window has border // This solves a number of glitches and on top of this // it optimizes painting quite a bit const bool blitInTempPixmap = xRenderOffscreen() || (data.crossFadeProgress() < 1.0 && !opaque) || (scaled && (wantShadow || (client && !client->noBorder()) || (deleted && !deleted->noBorder()))); xcb_render_picture_t renderTarget = m_scene->bufferPicture(); if (blitInTempPixmap) { if (scene_xRenderOffscreenTarget()) { temp_visibleRect = toplevel->visibleRect().translated(-toplevel->pos()); renderTarget = *scene_xRenderOffscreenTarget(); } else { prepareTempPixmap(); renderTarget = *s_tempPicture; } } else { xcb_render_set_picture_transform(connection(), pic, xform); if (filter == ImageFilterGood) { setPictureFilter(pic, KWin::Scene::ImageFilterGood); } //BEGIN OF STUPID RADEON HACK // This is needed to avoid hitting a fallback in the radeon driver. // The Render specification states that sampling pixels outside the // source picture results in alpha=0 pixels. This can be achieved by // setting the border color to transparent black, but since the border // color has the same format as the texture, it only works when the // texture has an alpha channel. So the driver falls back to software // when the repeat mode is RepeatNone, the picture has a non-identity // transformation matrix, and doesn't have an alpha channel. // Since we only scale the picture, we can work around this by setting // the repeat mode to RepeatPad. if (!window()->hasAlpha()) { const uint32_t values[] = {XCB_RENDER_REPEAT_PAD}; xcb_render_change_picture(connection(), pic, XCB_RENDER_CP_REPEAT, values); } //END OF STUPID RADEON HACK } #define MAP_RECT_TO_TARGET(_RECT_) \ if (blitInTempPixmap) _RECT_.translate(-temp_visibleRect.topLeft()); else _RECT_ = mapToScreen(mask, data, _RECT_) //BEGIN deco preparations bool noBorder = true; xcb_render_picture_t left = XCB_RENDER_PICTURE_NONE; xcb_render_picture_t top = XCB_RENDER_PICTURE_NONE; xcb_render_picture_t right = XCB_RENDER_PICTURE_NONE; xcb_render_picture_t bottom = XCB_RENDER_PICTURE_NONE; QRect dtr, dlr, drr, dbr; const SceneXRenderDecorationRenderer *renderer = nullptr; if (client) { if (client && !client->noBorder()) { if (client->isDecorated()) { SceneXRenderDecorationRenderer *r = static_cast<SceneXRenderDecorationRenderer*>(client->decoratedClient()->renderer()); if (r) { r->render(); renderer = r; } } noBorder = client->noBorder(); client->layoutDecorationRects(dlr, dtr, drr, dbr); } } if (deleted && !deleted->noBorder()) { renderer = static_cast<const SceneXRenderDecorationRenderer*>(deleted->decorationRenderer()); noBorder = deleted->noBorder(); deleted->layoutDecorationRects(dlr, dtr, drr, dbr); } if (renderer) { left = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Left); top = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Top); right = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Right); bottom = renderer->picture(SceneXRenderDecorationRenderer::DecorationPart::Bottom); } if (!noBorder) { MAP_RECT_TO_TARGET(dtr); MAP_RECT_TO_TARGET(dlr); MAP_RECT_TO_TARGET(drr); MAP_RECT_TO_TARGET(dbr); } //END deco preparations //BEGIN shadow preparations QRect stlr, str, strr, srr, sbrr, sbr, sblr, slr; SceneXRenderShadow* m_xrenderShadow = static_cast<SceneXRenderShadow*>(m_shadow); if (wantShadow) { m_xrenderShadow->layoutShadowRects(str, strr, srr, sbrr, sbr, sblr, slr, stlr); MAP_RECT_TO_TARGET(stlr); MAP_RECT_TO_TARGET(str); MAP_RECT_TO_TARGET(strr); MAP_RECT_TO_TARGET(srr); MAP_RECT_TO_TARGET(sbrr); MAP_RECT_TO_TARGET(sbr); MAP_RECT_TO_TARGET(sblr); MAP_RECT_TO_TARGET(slr); } //BEGIN end preparations //BEGIN client preparations QRect dr = cr; if (blitInTempPixmap) { dr.translate(-temp_visibleRect.topLeft()); } else { dr = mapToScreen(mask, data, dr); // Destination rect if (scaled) { cr.moveLeft(cr.x() * xscale); cr.moveTop(cr.y() * yscale); } } const int clientRenderOp = (opaque || blitInTempPixmap) ? XCB_RENDER_PICT_OP_SRC : XCB_RENDER_PICT_OP_OVER; //END client preparations #undef MAP_RECT_TO_TARGET for (PaintClipper::Iterator iterator; !iterator.isDone(); iterator.next()) { #define RENDER_SHADOW_TILE(_TILE_, _RECT_) \ xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, m_xrenderShadow->picture(SceneXRenderShadow::ShadowElement##_TILE_), \ shadowAlpha, renderTarget, 0, 0, 0, 0, _RECT_.x(), _RECT_.y(), _RECT_.width(), _RECT_.height()) //shadow if (wantShadow) { xcb_render_picture_t shadowAlpha = XCB_RENDER_PICTURE_NONE; if (!opaque) { shadowAlpha = xRenderBlendPicture(data.opacity()); } RENDER_SHADOW_TILE(TopLeft, stlr); RENDER_SHADOW_TILE(Top, str); RENDER_SHADOW_TILE(TopRight, strr); RENDER_SHADOW_TILE(Left, slr); RENDER_SHADOW_TILE(Right, srr); RENDER_SHADOW_TILE(BottomLeft, sblr); RENDER_SHADOW_TILE(Bottom, sbr); RENDER_SHADOW_TILE(BottomRight, sbrr); } #undef RENDER_SHADOW_TILE // Paint the window contents if (!(client && client->isShade())) { xcb_render_picture_t clientAlpha = XCB_RENDER_PICTURE_NONE; if (!opaque) { clientAlpha = xRenderBlendPicture(data.opacity()); } xcb_render_composite(connection(), clientRenderOp, pic, clientAlpha, renderTarget, cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); if (data.crossFadeProgress() < 1.0 && data.crossFadeProgress() > 0.0) { XRenderWindowPixmap *previous = previousWindowPixmap<XRenderWindowPixmap>(); if (previous && previous != pixmap) { static XRenderPicture cFadeAlpha(XCB_RENDER_PICTURE_NONE); static xcb_render_color_t cFadeColor = {0, 0, 0, 0}; cFadeColor.alpha = uint16_t((1.0 - data.crossFadeProgress()) * 0xffff); if (cFadeAlpha == XCB_RENDER_PICTURE_NONE) { cFadeAlpha = xRenderFill(cFadeColor); } else { xcb_rectangle_t rect = {0, 0, 1, 1}; xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, cFadeAlpha, cFadeColor , 1, &rect); } if (previous->size() != pixmap->size()) { xcb_render_transform_t xform2 = { DOUBLE_TO_FIXED(FIXED_TO_DOUBLE(xform.matrix11) * previous->size().width() / pixmap->size().width()), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(FIXED_TO_DOUBLE(xform.matrix22) * previous->size().height() / pixmap->size().height()), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1) }; xcb_render_set_picture_transform(connection(), previous->picture(), xform2); } xcb_render_composite(connection(), opaque ? XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_ATOP, previous->picture(), cFadeAlpha, renderTarget, cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); if (previous->size() != pixmap->size()) { xcb_render_set_picture_transform(connection(), previous->picture(), identity); } } } if (!opaque) transformed_shape = QRegion(); } if (client || deleted) { if (!noBorder) { xcb_render_picture_t decorationAlpha = xRenderBlendPicture(data.opacity()); auto renderDeco = [decorationAlpha, renderTarget](xcb_render_picture_t deco, const QRect &rect) { if (deco == XCB_RENDER_PICTURE_NONE) { return; } xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, deco, decorationAlpha, renderTarget, 0, 0, 0, 0, rect.x(), rect.y(), rect.width(), rect.height()); }; renderDeco(top, dtr); renderDeco(left, dlr); renderDeco(right, drr); renderDeco(bottom, dbr); } } if (data.brightness() != 1.0) { // fake brightness change by overlaying black const float alpha = (1 - data.brightness()) * data.opacity(); xcb_rectangle_t rect; if (blitInTempPixmap) { rect.x = -temp_visibleRect.left(); rect.y = -temp_visibleRect.top(); rect.width = width(); rect.height = height(); } else { rect.x = wr.x(); rect.y = wr.y(); rect.width = wr.width(); rect.height = wr.height(); } xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_OVER, renderTarget, preMultiply(data.brightness() < 1.0 ? QColor(0,0,0,255*alpha) : QColor(255,255,255,-alpha*255)), 1, &rect); } if (blitInTempPixmap) { const QRect r = mapToScreen(mask, data, temp_visibleRect); xcb_render_set_picture_transform(connection(), *s_tempPicture, xform); setPictureFilter(*s_tempPicture, filter); xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, *s_tempPicture, XCB_RENDER_PICTURE_NONE, m_scene->bufferPicture(), 0, 0, 0, 0, r.x(), r.y(), r.width(), r.height()); xcb_render_set_picture_transform(connection(), *s_tempPicture, identity); } } if (scaled && !blitInTempPixmap) { xcb_render_set_picture_transform(connection(), pic, identity); if (filter == ImageFilterGood) setPictureFilter(pic, KWin::Scene::ImageFilterFast); if (!window()->hasAlpha()) { const uint32_t values[] = {XCB_RENDER_REPEAT_NONE}; xcb_render_change_picture(connection(), pic, XCB_RENDER_CP_REPEAT, values); } } if (xRenderOffscreen()) scene_setXRenderOffscreenTarget(*s_tempPicture); }
IOHIDTableAcceleration * IOHIDTableAcceleration::CreateOriginalWithTable (CFDataRef table, double acceleration, const double resolution, const double rate) { double scale; UInt32 count; Boolean isLower; ACCEL_POINT lower, upper, p1, p2, p3, prev, curveP1, curveP2; double loAccel, hiAccel; const void * loTable = NULL; const void * hiTable = NULL; unsigned int loCount, hiCount; p1 = prev = curveP1 = curveP2 = {0,0}; loCount = hiCount = 0; loAccel = 0; if( table == NULL || resolution == 0 || rate == 0) { return NULL; } IOHIDTableAcceleration * self = new IOHIDTableAcceleration; if (self == NULL) { return NULL; } self->resolution_ = resolution; self->rate_ = rate; hiTable = CFDataGetBytePtr(table); scale = FIXED_TO_DOUBLE(ACCEL_TABLE_CONSUME_INT32(&hiTable)); ACCEL_TABLE_CONSUME_INT32(&hiTable); // normalize table's default (scale) to 0.5 if( acceleration > 0.5) { acceleration = (acceleration - 0.5) * (1 - scale ) * 2 + scale ; } else { acceleration = acceleration * scale ; } count = ACCEL_TABLE_CONSUME_INT16(&hiTable); scale = 1.0; // find curves bracketing the desired value do { hiAccel = FIXED_TO_DOUBLE(ACCEL_TABLE_CONSUME_INT32(&hiTable)); hiCount = ACCEL_TABLE_CONSUME_INT16 (&hiTable); if( acceleration <= hiAccel) { break; } if( 0 == --count) { // this much over the highest table scale = (hiAccel) ? (acceleration / hiAccel ) : 0; loTable = NULL; break; } loTable = hiTable; loAccel = hiAccel; loCount = hiCount; hiTable = (uint8_t*)hiTable + loCount * 8; } while (true); // scale between the two if( loTable) { scale = (hiAccel == loAccel) ? 0 : (acceleration - loAccel) / (hiAccel - loAccel); } // or take all the high one else { loTable = hiTable; //loAccel = hiAccel; loCount = 0; } lower = ACCELL_TABLE_CONSUME_POINT(&loTable); upper = ACCELL_TABLE_CONSUME_POINT(&hiTable); do { // consume next point from first X isLower = (loCount && (!hiCount || (lower.x <= upper.x))); if( isLower) { /* highline */ p2 = upper; p3 = lower; if( loCount && (--loCount)) { lower = ACCELL_TABLE_CONSUME_POINT(&loTable); } } else { /* lowline */ p2 = lower; p3 = upper; if( hiCount && (--hiCount)) { upper = ACCELL_TABLE_CONSUME_POINT(&hiTable); } } { curveP2 = InterpolatePoint(p3, p1, p2 , scale, isLower); curveP2.x *= (resolution/rate); curveP2.y *= kCursorScale; ACCEL_SEGMENT segment; segment.m = (curveP2.x == curveP1.x) ? 0 : (curveP2.y - curveP1.y) / (curveP2.x - curveP1.x), segment.b = curveP2.y - segment.m * curveP2.x, segment.x = (loCount || hiCount) ? curveP2.x : MAX_DEVICE_THRESHOLD; self->segments_.push_back ({ segment }); curveP1 = curveP2; } // continue on from last point if( loCount && hiCount) { if( lower.x > upper.x) { prev = p1; } else { prev = p1; p1 = p3; } } else { p2 = p1; p1 = prev; prev = p2; } } while( loCount || hiCount ); return self; }