SidekickAnim::SidekickAnim (CompWindow *w, WindowEvent curWindowEvent, float duration, const AnimEffect info, const CompRect &icon) : Animation::Animation (w, curWindowEvent, duration, info, icon), TransformAnim::TransformAnim (w, curWindowEvent, duration, info, icon), ZoomAnim::ZoomAnim (w, curWindowEvent, duration, info, icon) { // determine number of rotations randomly in [0.9, 1.1] range mNumRotations = optValF (AnimationOptions::SidekickNumRotations) * (1.0f + 0.2f * rand () / RAND_MAX - 0.1f); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); float winCenterX = outRect.x () + outRect.width () / 2.0; float iconCenterX = mIcon.x () + mIcon.width () / 2.0; // if window is to the right of icon, rotate clockwise instead // to make rotation look more pleasant if (winCenterX > iconCenterX) mNumRotations *= -1; }
void CompositeWindow::damageTransformedRect (float xScale, float yScale, float xTranslate, float yTranslate, const CompRect &rect) { int x1, x2, y1, y2; x1 = (short) (rect.x1 () * xScale) - 1; y1 = (short) (rect.y1 () * yScale) - 1; x2 = (short) (rect.x2 () * xScale + 0.5f) + 1; y2 = (short) (rect.y2 () * yScale + 0.5f) + 1; x1 += (short) xTranslate; y1 += (short) yTranslate; x2 += (short) (xTranslate + 0.5f); y2 += (short) (yTranslate + 0.5f); if (x2 > x1 && y2 > y1) { const CompWindow::Geometry &geom = priv->window->serverGeometry (); x1 += geom.x () + geom.border (); y1 += geom.y () + geom.border (); x2 += geom.x () + geom.border (); y2 += geom.y () + geom.border (); priv->cScreen->damageRegion (CompRegion (CompRect (x1, y1, x2 - x1, y2 - y1))); } }
bool CompRegion::intersects (const CompRect &r) const { int result; result = XRectInRegion (handle (), r.x (), r.y (), r.width (), r.height ()); return result != RectangleOut; }
bool CompRegion::contains (const CompRect &r) const { int result; result = XRectInRegion (handle (), r.x (), r.y (), r.width (), r.height ()); return result == RectangleIn; }
void ResizeWindow::getStretchScale (BoxPtr pBox, float *xScale, float *yScale) { CompRect rect (window->borderRect ()); *xScale = (rect.width ()) ? (pBox->x2 - pBox->x1) / (float) rect.width () : 1.0f; *yScale = (rect.height ()) ? (pBox->y2 - pBox->y1) / (float) rect.height () : 1.0f; }
Point ZoomAnim::getCenter () { Point center; if (zoomToIcon ()) { getCenterScale (¢er, 0); } else { float forwardProgress = progressLinear (); CompRect inRect (mAWindow->savedRectsValid () ? mAWindow->savedInRect () : mWindow->borderRect ()); center.setX (inRect.x () + inRect.width () / 2.0); if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { float origCenterY = (inRect.y () + inRect.height () / 2.0); center.setY ((1 - forwardProgress) * origCenterY + forwardProgress * (inRect.y () + mDecorTopHeight)); } else // i.e. (un)minimizing without zooming { center.setY (inRect.y () + inRect.height () / 2.0); } } return center; }
void GridAnim::init () { initGrid (); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); mModel = new GridModel (mWindow, mCurWindowEvent, outRect.height (), mGridWidth, mGridHeight, mDecorTopHeight, mDecorBottomHeight); }
void calculateWallOffset (const CompRect &output, const CompPoint &offsetInScreenCoords, const CompPoint &vpSize, const CompSize &screenSize, float &offsetInWorldX, float &offsetInWorldY, float &worldScaleFactorX, float &worldScaleFactorY, float animationProgress) { const float sx = screenSize.width () / static_cast <float> (output.width ()); const float sy = screenSize.height () / static_cast <float> (output.height ()); offsetInWorldX = 0.0; offsetInWorldY = 0.0; worldScaleFactorX = 1.0f; worldScaleFactorY = 1.0f; if (output.left () == 0) { offsetInWorldX = ((vpSize.x () * sx) / ((float) output.width ()) * (offsetInScreenCoords.x ()) * animationProgress); worldScaleFactorX = 1.0f - ((float) (offsetInScreenCoords.x ()) / (float) (output.width ())) * animationProgress; } if (output.top () == 0) { offsetInWorldY = ((vpSize.y () * sy) / ((float) output.height ()) * (offsetInScreenCoords.y ()) * animationProgress); worldScaleFactorY = 1.0f - ((float) (offsetInScreenCoords.y ()) / (float) output.height ()) * animationProgress; } }
void LeafSpreadAnim::init () { if (!tessellateIntoRectangles (20, 14, 15.0f)) return; CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); float fadeDuration = 0.26; float life = 0.4; float spreadFac = 3.5; float randYMax = 0.07; float winFacX = outRect.width () / 800.0; float winFacY = outRect.height () / 800.0; float winFacZ = (outRect.height () + outRect.width ()) / 2.0 / 800.0; float screenSizeFactor = (0.8 * DEFAULT_Z_CAMERA * ::screen->width ()); foreach (PolygonObject *p, mPolygons) { p->rotAxis.set (RAND_FLOAT (), RAND_FLOAT (), RAND_FLOAT ()); float speed = screenSizeFactor / 10 * (0.2 + RAND_FLOAT ()); float xx = 2 * (p->centerRelPos.x () - 0.5); float yy = 2 * (p->centerRelPos.y () - 0.5); float x = speed * winFacX * spreadFac * (xx + 0.5 * (RAND_FLOAT () - 0.5)); float y = speed * winFacY * spreadFac * (yy + 0.5 * (RAND_FLOAT () - 0.5)); float z = speed * winFacZ * 7 * ((RAND_FLOAT () - 0.5) / 0.5); p->finalRelPos.set (x, y, z); p->moveStartTime = p->centerRelPos.y () * (1 - fadeDuration - randYMax) + randYMax * RAND_FLOAT (); p->moveDuration = 1; p->fadeStartTime = p->moveStartTime + life; if (p->fadeStartTime > 1 - fadeDuration) p->fadeStartTime = 1 - fadeDuration; p->fadeDuration = fadeDuration; p->finalRotAng = 150; }
void PrivateGLWindow::updateWindowRegions () { CompRect input (window->serverInputRect ()); if (regions.size () != textures.size ()) regions.resize (textures.size ()); for (unsigned int i = 0; i < textures.size (); i++) { regions[i] = CompRegion (*textures[i]); regions[i].translate (input.x (), input.y ()); regions[i] &= window->region (); } updateState &= ~(UpdateRegion); }
CompRegion::CompRegion (const CompRect &r) { priv = new PrivateRegion (); priv->box.extents = r.region ()->extents; priv->box.numRects = 1; priv->box.rects = &priv->box.extents; }
void CompOutput::setWorkArea (const CompRect &workarea) { mWorkArea = workarea; if (workarea.x () < static_cast <int> (x1 ())) mWorkArea.setX (x1 ()); if (workarea.y () < static_cast <int> (y1 ())) mWorkArea.setY (y1 ()); if (workarea.x2 () > static_cast <int> (x2 ())) mWorkArea.setWidth (x2 () - mWorkArea.x ()); if (workarea.y2 () > static_cast <int> (y2 ())) mWorkArea.setHeight (y2 () - mWorkArea.y ()); }
void CompOutput::setWorkArea (const CompRect& workarea) { mWorkArea = workarea; if (workarea.x () < (int) x1 ()) mWorkArea.setX (x1 ()); if (workarea.y () < (int) y1 ()) mWorkArea.setY (y1 ()); if (workarea.x2 () > (int) x2 ()) mWorkArea.setWidth (x2 () - mWorkArea.x ()); if (workarea.y2 () > (int) y2 ()) mWorkArea.setHeight (y2 () - mWorkArea.y ()); }
CompRegion CompRegion::united (const CompRect &r) const { CompRegion rv; rv.priv->makeReal (); XUnionRegion (handle (), r.region (), rv.handle ()); return rv; }
CompRegion CompRegion::subtracted (const CompRect &r) const { CompRegion rv; rv.priv->makeReal (); XSubtractRegion (handle (), r.region (), rv.handle ()); return rv; }
void PrivateGLWindow::setWindowMatrix () { CompRect input (window->inputRect ()); if (textures.size () != matrices.size ()) matrices.resize (textures.size ()); for (unsigned int i = 0; i < textures.size (); i++) { matrices[i] = textures[i]->matrix (); matrices[i].x0 -= (input.x () * matrices[i].xx); matrices[i].y0 -= (input.y () * matrices[i].yy); } updateState &= ~(UpdateMatrix); }
ZoomAnim::ZoomAnim (CompWindow *w, WindowEvent curWindowEvent, float duration, const AnimEffect info, const CompRect &icon) : Animation::Animation (w, curWindowEvent, duration, info, icon), TransformAnim::TransformAnim (w, curWindowEvent, duration, info, icon), FadeAnim::FadeAnim (w, curWindowEvent, duration, info, icon) { CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); if (isZoomFromCenter ()) { mIcon.setX (outRect.x () + outRect.width () / 2 - mIcon.width () / 2); mIcon.setY (outRect.y () + outRect.height () / 2 - mIcon.height () / 2); } }
void SvgWindow::updateSvgMatrix () { SvgTexture *texture; GLTexture::Matrix *m; unsigned int i; CompRect rect; rect = context->box.boundingRect (); texture = &context->texture[0]; if (texture->matrices.size () != texture->textures.size ()) texture->matrices.resize (texture->textures.size ()); for (i = 0; i < texture->textures.size (); i++) { m = &texture->matrices[i]; *m = texture->textures[i]->matrix (); m->xx *= (float) texture->size.width () / rect.width (); m->yy *= (float) texture->size.height () / rect.height (); m->x0 -= (rect.x () * m->xx); m->y0 -= (rect.y () * m->yy); } texture = &context->texture[1]; if (texture->matrices.size () != texture->textures.size ()) texture->matrices.resize (texture->textures.size ()); for (i = 0; i < texture->textures.size (); i++) { m = &texture->matrices[i]; *m = texture->textures[i]->matrix (); m->xx *= (float) texture->size.width () / context->rect.width (); m->yy *= (float) texture->size.height () / context->rect.height (); m->x0 -= (context->rect.x () * m->xx); m->y0 -= (context->rect.y () * m->yy); } }
void reserveStruts (CompRect &workArea) { workArea.setLeft (workArea.left () + 24); workArea.setTop (workArea.top () + 24); workArea.setBottom (workArea.bottom () - 24); }
void CompositeWindow::addDamageRect (const CompRect &rect) { if (priv->cScreen->damageMask () & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) return; if (!damageRect (false, rect)) { int x, y; x = rect.x (); y = rect.y (); const CompWindow::Geometry &geom = priv->window->geometry (); x += geom.x () + geom.border (); y += geom.y () + geom.border (); priv->cScreen->damageRegion (CompRegion (CompRect (x, y, rect.width (), rect.height ()))); } }
void WSNamesScreen::drawText (const GLMatrix &matrix) { GLfloat alpha; float x, y, border = 10.0f; CompRect oe = screen->getCurrentOutputExtents (); x = oe.centerX () - textData.getWidth () / 2; /* assign y (for the lower corner!) according to the setting */ switch (optionGetTextPlacement ()) { case WorkspacenamesOptions::TextPlacementCenteredOnScreen: y = oe.centerY () + textData.getHeight () / 2; break; case WorkspacenamesOptions::TextPlacementTopOfScreen: case WorkspacenamesOptions::TextPlacementBottomOfScreen: { CompRect workArea = screen->currentOutputDev ().workArea (); if (optionGetTextPlacement () == WorkspacenamesOptions::TextPlacementTopOfScreen) y = oe.y1 () + workArea.y () + (2 * border) + textData.getHeight (); else y = oe.y1 () + workArea.y () + workArea.height () - (2 * border); } break; default: return; break; } if (timer) alpha = timer / (optionGetFadeTime () * 1000.0f); else alpha = 1.0f; textData.draw (matrix, floor (x), floor (y), alpha); }
void ZoomAnim::getCenterScaleFull (Point *pCurCenter, Point *pCurScale, Point *pWinCenter, Point *pIconCenter, float *pMoveProgress) { CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); Point winCenter ((outRect.x () + outRect.width () / 2.0), (outRect.y () + outRect.height () / 2.0)); Point iconCenter (mIcon.x () + mIcon.width () / 2.0, mIcon.y () + mIcon.height () / 2.0); Point winSize (outRect.width (), outRect.height ()); winSize.setX (winSize.x () == 0 ? 1 : winSize.x ()); winSize.setY (winSize.y () == 0 ? 1 : winSize.y ()); float scaleProgress; float moveProgress; getZoomProgress (&moveProgress, &scaleProgress, neverSpringy ()); Point curCenter ((1 - moveProgress) * winCenter.x () + moveProgress * iconCenter.x (), (1 - moveProgress) * winCenter.y () + moveProgress * iconCenter.y ()); Point curScale (((1 - scaleProgress) * winSize.x () + scaleProgress * mIcon.width ()) / winSize.x (), ((1 - scaleProgress) * winSize.y () + scaleProgress * mIcon.height ()) / winSize.y ()); // Copy calculated variables if (pCurCenter) *pCurCenter = curCenter; if (pCurScale) *pCurScale = curScale; if (pWinCenter) *pWinCenter = winCenter; if (pIconCenter) *pIconCenter = iconCenter; if (pMoveProgress) *pMoveProgress = moveProgress; }
void BurnAnim::step () { CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); float timestep = mIntenseTimeStep; float old = 1 - (mRemainingTime) / (mTotalTime - timestep); float stepSize; mRemainingTime -= timestep; if (mRemainingTime <= 0) mRemainingTime = 0; // avoid sub-zero values float newProgress = 1 - (mRemainingTime) / (mTotalTime - timestep); stepSize = newProgress - old; if (mCurWindowEvent == WindowEventOpen || mCurWindowEvent == WindowEventUnminimize || mCurWindowEvent == WindowEventUnshade) { newProgress = 1 - newProgress; } if (mRemainingTime > 0) { CompRect rect; switch (mDirection) { case AnimDirectionUp: rect = CompRect (0, 0, outRect.width (), outRect.height () - (newProgress * outRect.height ())); break; case AnimDirectionRight: rect = CompRect (newProgress * outRect.width (), 0, outRect.width () - (newProgress * outRect.width ()), outRect.height ()); break; case AnimDirectionLeft: rect = CompRect (0, 0, outRect.width () - (newProgress * outRect.width ()), outRect.height ()); break; case AnimDirectionDown: default: rect = CompRect (0, newProgress * outRect.height (), outRect.width (), outRect.height () - (newProgress * outRect.height ())); break; } rect.setX (rect.x () + outRect.x ()); rect.setY (rect.y () + outRect.y ()); mDrawRegion = CompRegion (rect); } else { mDrawRegion = emptyRegion; } mUseDrawRegion = (fabs (newProgress) > 1e-5); if (mRemainingTime > 0) { switch (mDirection) { case AnimDirectionUp: if (mHasSmoke) genNewSmoke (outRect.x (), outRect.y () + ((1 - newProgress) * outRect.height ()), outRect.width (), 1, outRect.width () / 40.0, mTimeSinceLastPaint); genNewFire (outRect.x (), outRect.y () + ((1 - newProgress) * outRect.height ()), outRect.width (), (stepSize) * outRect.height (), outRect.width () / 40.0, mTimeSinceLastPaint); break; case AnimDirectionLeft: if (mHasSmoke) genNewSmoke (outRect.x () + ((1 - newProgress) * outRect.width ()), outRect.y (), (stepSize) * outRect.width (), outRect.height (), outRect.height () / 40.0, mTimeSinceLastPaint); genNewFire (outRect.x () + ((1 - newProgress) * outRect.width ()), outRect.y (), (stepSize) * outRect.width (), outRect.height (), outRect.height () / 40.0, mTimeSinceLastPaint); break; case AnimDirectionRight: if (mHasSmoke) genNewSmoke (outRect.x () + (newProgress * outRect.width ()), outRect.y (), (stepSize) * outRect.width (), outRect.height (), outRect.height () / 40.0, mTimeSinceLastPaint); genNewFire (outRect.x () + (newProgress * outRect.width ()), outRect.y (), (stepSize) * outRect.width (), outRect.height (), outRect.height () / 40.0, mTimeSinceLastPaint); break; case AnimDirectionDown: default: if (mHasSmoke) genNewSmoke (outRect.x (), outRect.y () + (newProgress * outRect.height ()), outRect.width (), 1, outRect.width () / 40.0, mTimeSinceLastPaint); genNewFire (outRect.x (), outRect.y () + (newProgress * outRect.height ()), outRect.width (), (stepSize) * outRect.height (), outRect.width () / 40.0, mTimeSinceLastPaint); break; } } if (mRemainingTime <= 0 && (mParticleSystems[0].active () || (mHasSmoke && mParticleSystems[1].active ()))) // force animation to continue until particle systems are done mRemainingTime = timestep; Particle *part; if (mRemainingTime > 0) { int nParticles; if (mHasSmoke) { float partxg = outRect.width () / 40.0; float partxgNeg = -partxg; vector<Particle> &particles = mParticleSystems[mSmokePSId].particles (); nParticles = particles.size (); part = &particles[0]; for (int i = 0; i < nParticles; i++, part++) part->xg = (part->x < part->xo) ? partxg : partxgNeg; mParticleSystems[mSmokePSId].setOrigin (outRect.x (), outRect.y ()); } vector<Particle> &particles = mParticleSystems[mFirePSId].particles (); nParticles = particles.size (); part = &particles[0]; for (int i = 0; i < nParticles; i++, part++) part->xg = (part->x < part->xo) ? 1.0 : -1.0; } mParticleSystems[mFirePSId].setOrigin (outRect.x (), outRect.y ()); }
void HorizontalFoldsAnim::step () { GridZoomAnim::step (); CompRect winRect (mAWindow->savedRectsValid () ? mAWindow->saveWinRect () : mWindow->geometry ()); CompRect inRect (mAWindow->savedRectsValid () ? mAWindow->savedInRect () : mWindow->inputRect ()); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); CompWindowExtents outExtents (mAWindow->savedRectsValid () ? mAWindow->savedOutExtents () : mWindow->output ()); int wx = winRect.x (); int wy = winRect.y (); int oy = outRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); float winHeight = 0; if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { winHeight = winRect.height (); } else { winHeight = inRect.height (); } int nHalfFolds = 2.0 * optValI (AnimationOptions::HorizontalFoldsNumFolds); float foldMaxAmp = 0.3 * pow ((winHeight / nHalfFolds) / ::screen->height (), 0.3) * optValF (AnimationOptions::HorizontalFoldsAmpMult); float forwardProgress = getActualProgress (); float sinForProg = sin (forwardProgress * M_PI / 2); GridModel::GridObject *object = mModel->objects (); unsigned int n = mModel->numObjects (); for (unsigned int i = 0; i < n; ++i, ++object) { Point3d &objPos = object->position (); if (i % 2 == 0) // object is at the left side { float objGridY = object->gridPosition ().y (); int rowNo = (int)i / mGridWidth; float origy = (wy + (oheight * objGridY - outExtents.top) * mModel->scale ().y ()); if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { // Execute shade mode if (objGridY == 0) { objPos.setY (oy); objPos.setZ (0); } else if (objGridY == 1) { objPos.setY ( (1 - forwardProgress) * origy + forwardProgress * (oy + mDecorTopHeight + mDecorBottomHeight)); objPos.setZ (0); } else { float relDistToFoldCenter = (rowNo % 2 == 1 ? 0.5 : 0); objPos.setY ( (1 - forwardProgress) * origy + forwardProgress * (oy + mDecorTopHeight)); objPos.setZ ( getObjectZ (mModel, forwardProgress, sinForProg, relDistToFoldCenter, foldMaxAmp)); } } else { // Execute normal mode float relDistToFoldCenter = (rowNo % 2 == 0 ? 0.5 : 0); objPos.setY ( (1 - forwardProgress) * origy + forwardProgress * (inRect.y () + inRect.height () / 2.0)); objPos.setZ ( getObjectZ (mModel, forwardProgress, sinForProg, relDistToFoldCenter, foldMaxAmp)); } } else // object is at the right side { // Set y/z position to the y/z position of the object at the left // on the same row (previous object) Point3d &leftObjPos = (object - 1)->position (); objPos.setY (leftObjPos.y ()); objPos.setZ (leftObjPos.z ()); } float origx = (wx + (owidth * object->gridPosition ().x () - outExtents.left) * mModel->scale ().x ()); objPos.setX (origx); } }
bool SvgWindow::glDraw (const GLMatrix &transform, const GLWindowPaintAttrib &attrib, const CompRegion ®ion, unsigned int mask) { bool status = gWindow->glDraw (transform, attrib, region, mask); if (!status) return status; const CompRegion ® = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ? infiniteRegion : region; if (context && reg.numRects ()) { GLTexture::MatrixList matrix (1); int x1, y1, x2, y2; CompRect rect = context->box.boundingRect (); x1 = MIN (rect.x1 (), sScreen->zoom.x1 ()); y1 = MIN (rect.y1 (), sScreen->zoom.y1 ()); x2 = MAX (rect.x2 (), sScreen->zoom.x2 ()); y2 = MAX (rect.y2 (), sScreen->zoom.y2 ()); rect.setGeometry (x1, y1, x2 - x1, y2 - y1); for (unsigned int i = 0; i < context->texture[0].textures.size (); i++) { matrix[0] = context->texture[0].matrices[i]; gWindow->vertexBuffer ()->begin (); gWindow->glAddGeometry (matrix, context->box, reg); gWindow->vertexBuffer ()->end (); if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) mask |= PAINT_WINDOW_BLEND_MASK; gWindow->glDrawTexture (context->texture[0].textures[i], transform, attrib, mask); if (rect.width () > 0 && rect.height () > 0) { float xScale, yScale; float dx, dy; int width, height; rect.setGeometry (rect.x1 () - 1, rect.y1 () - 1, rect.width () + 1, rect.height () + 1); xScale = screen->width () / (float) (sScreen->zoom.width ()); yScale = screen->height () / (float) (sScreen->zoom.height ()); dx = rect.width (); dy = rect.height (); width = dx * xScale + 0.5f; height = dy * yScale + 0.5f; if (rect != context->rect || width != context->size.width () || height != context->size.height ()) { float x1, y1, x2, y2; context->rect = rect; context->size.setWidth (width); context->size.setHeight (height); dx = context->box.boundingRect ().width (); dy = context->box.boundingRect ().height (); x1 = (rect.x1 () - context->box.boundingRect ().x ()) / dx; y1 = (rect.y1 () - context->box.boundingRect ().y ()) / dy; x2 = (rect.x2 () - context->box.boundingRect ().x ()) / dx; y2 = (rect.y2 () - context->box.boundingRect ().y ()) / dy; finiTexture (context->texture[1]); if (initTexture (context->source, context->texture[1], context->size)) { renderSvg (context->source, context->texture[1], context->size, x1, y1, x2, y2); updateSvgMatrix (); } } for (unsigned int j = 0; j < context->texture[1].textures.size (); j++) { GLTexture::Filter saveFilter; CompRegion r (rect); matrix[0] = context->texture[1].matrices[j]; saveFilter = gScreen->filter (SCREEN_TRANS_FILTER); gScreen->setFilter (SCREEN_TRANS_FILTER, GLTexture::Good); gWindow->vertexBuffer ()->begin (); gWindow->glAddGeometry (matrix, r, reg); gWindow->vertexBuffer ()->end (); gWindow->glDrawTexture (context->texture[1].textures[j], transform, attrib, mask); gScreen->setFilter (SCREEN_TRANS_FILTER, saveFilter); } } else if (context->texture[1].size.width ()) { finiTexture (context->texture[1]); initTexture (source, context->texture[1], CompSize ()); memset (&context->rect, 0, sizeof (BoxRec)); context->size.setWidth (0); context->size.setHeight (0); } } } return status; }
void GridAnim::addGeometry (const GLTexture::MatrixList &matrix, const CompRegion ®ion, const CompRegion &clip, unsigned int maxGridWidth, unsigned int maxGridHeight) { unsigned int nMatrix = matrix.size (); int nVertices, nIndices; GLushort *i; GLfloat *v; int x1, y1, x2, y2; float winContentsY, winContentsHeight; float deformedX, deformedY; float deformedZ = 0; int nVertX, nVertY; int vSize; float gridW, gridH; bool rect = true; bool notUsing3dCoords = !using3D (); if (region.isEmpty ()) // nothing to do return; GLWindow::Geometry &geometry = GLWindow::get (mWindow)->geometry (); for (unsigned int it = 0; it < nMatrix; it++) { if (matrix[it].xy != 0.0f || matrix[it].yx != 0.0f) { rect = false; break; } } CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); CompWindowExtents outExtents (mAWindow->savedRectsValid () ? mAWindow->savedOutExtents () : mWindow->output ()); // window output (contents + decorations + shadows) coordinates and size int ox = outRect.x (); int oy = outRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); // to be used if event is shade/unshade winContentsY = oy + outExtents.top; winContentsHeight = oheight - outExtents.top - outExtents.bottom; geometry.texUnits = (int)nMatrix; if (geometry.vCount == 0) { // reset geometry.indexCount = 0; geometry.texCoordSize = 4; } geometry.vertexStride = 3 + geometry.texUnits * geometry.texCoordSize; vSize = geometry.vertexStride; nVertices = geometry.vCount; nIndices = geometry.indexCount; v = geometry.vertices + (nVertices * vSize); i = geometry.indices + nIndices; // For each clip passed to this function foreach (const CompRect &pClip, region.rects ()) { x1 = pClip.x1 (); y1 = pClip.y1 (); x2 = pClip.x2 (); y2 = pClip.y2 (); gridW = (float)owidth / (mGridWidth - 1); if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { if (y1 < winContentsY) // if at top part { gridH = mDecorTopHeight; } else if (y2 > winContentsY + winContentsHeight) // if at bottom { gridH = mDecorBottomHeight; } else // in window contents (only in Y coords) { float winContentsHeight = oheight - (mDecorTopHeight + mDecorBottomHeight); gridH = winContentsHeight / (mGridHeight - 3); } } else gridH = (float)oheight / (mGridHeight - 1); // nVertX, nVertY: number of vertices for this clip in x and y dimensions // + 2 to avoid running short of vertices in some cases nVertX = ceil ((x2 - x1) / gridW) + 2; nVertY = (gridH ? ceil ((y2 - y1) / gridH) : 0) + 2; // Allocate 4 indices for each quad int newIndexSize = nIndices + ((nVertX - 1) * (nVertY - 1) * 4); if (newIndexSize > geometry.indexSize) { if (!geometry.moreIndices (newIndexSize)) return; i = geometry.indices + nIndices; } // Assign quad vertices to indices for (int jy = 0; jy < nVertY - 1; jy++) { for (int jx = 0; jx < nVertX - 1; jx++) { *i++ = nVertices + nVertX * (2 * jy + 1) + jx; *i++ = nVertices + nVertX * (2 * jy + 1) + jx + 1; *i++ = nVertices + nVertX * 2 * jy + jx + 1; *i++ = nVertices + nVertX * 2 * jy + jx; nIndices += 4; } } // Allocate vertices int newVertexSize = (nVertices + nVertX * (2 * nVertY - 2)) * vSize; if (newVertexSize > geometry.vertexSize) { if (!geometry.moreVertices (newVertexSize)) return; v = geometry.vertices + (nVertices * vSize); } float rowTexCoordQ = 1; float prevRowCellWidth = 0; // this initial value won't be used float rowCellWidth = 0; int clipRowSize = nVertX * vSize; // For each vertex float y = y1; for (int jy = 0; jy < nVertY; jy++) { float topiyFloat; bool applyOffsets = true; if (y > y2) y = y2; // Do calculations for y here to avoid repeating // them unnecessarily in the x loop if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { if (y1 < winContentsY) // if at top part { topiyFloat = (y - oy) / mDecorTopHeight; topiyFloat = MIN (topiyFloat, 0.999); // avoid 1.0 applyOffsets = false; } else if (y2 > winContentsY + winContentsHeight) // if at bottom { topiyFloat = (mGridHeight - 2) + (mDecorBottomHeight ? (y - winContentsY - winContentsHeight) / mDecorBottomHeight : 0); applyOffsets = false; } else // in window contents (only in Y coords) { topiyFloat = (mGridHeight - 3) * (y - winContentsY) / winContentsHeight + 1; } } else { topiyFloat = (mGridHeight - 1) * (y - oy) / oheight; } // topiy should be at most (mGridHeight - 2) int topiy = (int)(topiyFloat + 1e-4); if (topiy == mGridHeight - 1) topiy--; int bottomiy = topiy + 1; float iny = topiyFloat - topiy; float inyRest = 1 - iny; // End of calculations for y float x = x1; for (int jx = 0; jx < nVertX; jx++) { if (x > x2) x = x2; // find containing grid cell (leftix rightix) x (topiy bottomiy) float leftixFloat = (mGridWidth - 1) * (x - ox) / owidth; int leftix = (int)(leftixFloat + 1e-4); if (leftix == mGridWidth - 1) leftix--; int rightix = leftix + 1; // GridModel::GridObjects that are at top, bottom, left, right corners of quad GridModel::GridObject *objToTopLeft = &(mModel->mObjects[topiy * mGridWidth + leftix]); GridModel::GridObject *objToTopRight = &(mModel->mObjects[topiy * mGridWidth + rightix]); GridModel::GridObject *objToBottomLeft = &(mModel->mObjects[bottomiy * mGridWidth + leftix]); GridModel::GridObject *objToBottomRight = &(mModel->mObjects[bottomiy * mGridWidth + rightix]); Point3d &objToTopLeftPos = objToTopLeft->mPosition; Point3d &objToTopRightPos = objToTopRight->mPosition; Point3d &objToBottomLeftPos = objToBottomLeft->mPosition; Point3d &objToBottomRightPos = objToBottomRight->mPosition; // find position in cell by taking remainder of flooring float inx = leftixFloat - leftix; float inxRest = 1 - inx; // Interpolate to find deformed coordinates float hor1x = (inxRest * objToTopLeftPos.x () + inx * objToTopRightPos.x ()); float hor1y = (inxRest * objToTopLeftPos.y () + inx * objToTopRightPos.y ()); float hor1z = (notUsing3dCoords ? 0 : inxRest * objToTopLeftPos.z () + inx * objToTopRightPos.z ()); float hor2x = (inxRest * objToBottomLeftPos.x () + inx * objToBottomRightPos.x ()); float hor2y = (inxRest * objToBottomLeftPos.y () + inx * objToBottomRightPos.y ()); float hor2z = (notUsing3dCoords ? 0 : inxRest * objToBottomLeftPos.z () + inx * objToBottomRightPos.z ()); deformedX = inyRest * hor1x + iny * hor2x; deformedY = inyRest * hor1y + iny * hor2y; deformedZ = inyRest * hor1z + iny * hor2z; // Texture coordinates (s, t, r, q) if (mUseQTexCoord) { if (jx == 1) rowCellWidth = deformedX - v[-3]; // do only once per row for all rows except row 0 if (jy > 0 && jx == 1) { rowTexCoordQ = (rowCellWidth / prevRowCellWidth); for (unsigned int it = 0; it < nMatrix; it++, v += 4) { // update first column // (since we didn't know rowTexCoordQ before) v[-vSize] *= rowTexCoordQ; // multiply s & t by q v[-vSize + 1] *= rowTexCoordQ; v[-vSize + 3] = rowTexCoordQ; // copy q } v -= nMatrix * 4; } } // Loop for each texture element // (4 texture coordinates for each one) for (unsigned int it = 0; it < nMatrix; it++, v += 4) { float offsetY = 0; if (rect) { if (applyOffsets && y < y2) offsetY = objToTopLeft->mOffsetTexCoordForQuadAfter.y (); v[0] = COMP_TEX_COORD_X (matrix[it], x); // s v[1] = COMP_TEX_COORD_Y (matrix[it], y + offsetY); // t } else { if (applyOffsets && y < y2) // FIXME: // The correct y offset below produces wrong // texture coordinates for some reason. offsetY = 0; // offsetY = objToTopLeft->offsetTexCoordForQuadAfter.y; v[0] = COMP_TEX_COORD_XY (matrix[it], x, y + offsetY); // s v[1] = COMP_TEX_COORD_YX (matrix[it], x, y + offsetY); // t } v[2] = 0; // r if (0 < jy && jy < nVertY - 1) { // copy s, t, r to duplicate row memcpy (v + clipRowSize, v, 3 * sizeof (GLfloat)); v[3 + clipRowSize] = 1; // q } if (applyOffsets && objToTopLeft->mOffsetTexCoordForQuadBefore.y () != 0) { // After copying to next row, update texture y coord // by following object's offset offsetY = objToTopLeft->mOffsetTexCoordForQuadBefore.y (); if (rect) { v[1] = COMP_TEX_COORD_Y (matrix[it], y + offsetY); } else { v[0] = COMP_TEX_COORD_XY (matrix[it], x, y + offsetY); v[1] = COMP_TEX_COORD_YX (matrix[it], x, y + offsetY); } } if (mUseQTexCoord) { v[3] = rowTexCoordQ; // q if (jx > 0) // since column 0 is updated when jx == 1 { // multiply s & t by q v[0] *= rowTexCoordQ; v[1] *= rowTexCoordQ; } } else { v[3] = 1; // q } } v[0] = deformedX; v[1] = deformedY; v[2] = deformedZ; // Copy vertex coordinates to duplicate row if (0 < jy && jy < nVertY - 1) memcpy (v + clipRowSize, v, 3 * sizeof (GLfloat)); nVertices++; // increment x properly (so that coordinates fall on grid intersections) x = rightix * gridW + ox; v += 3; // move on to next vertex } if (mUseQTexCoord) prevRowCellWidth = rowCellWidth; if (0 < jy && jy < nVertY - 1) { v += clipRowSize; // skip the duplicate row nVertices += nVertX; } // increment y properly (so that coordinates fall on grid intersections) if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { y += gridH; } else { y = bottomiy * gridH + oy; } } } geometry.vCount = nVertices; geometry.indexCount = nIndices; }
void RollUpAnim::step () { float forwardProgress = progressEaseInEaseOut (); bool fixedInterior = optValB (AnimationOptions::RollupFixedInterior); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); int ox = outRect.x (); int oy = outRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); GridModel::GridObject *object = mModel->objects (); unsigned int n = mModel->numObjects (); for (unsigned int i = 0; i < n; i++, object++) { // Executing shade mode Point3d &objPos = object->position (); if (i % 2 == 0) // object is at the left side { float objGridY = object->gridPosition ().y (); if (objGridY == 0) { objPos.setY (oy); } else if (objGridY == 1) { objPos.setY ( (1 - forwardProgress) * (oy + oheight * objGridY) + forwardProgress * (oy + mDecorTopHeight + mDecorBottomHeight)); } else { // find position in window contents // (window contents correspond to 0.0-1.0 range) float relPosInWinContents = (objGridY * oheight - mDecorTopHeight) / mWindow->height (); if (relPosInWinContents > forwardProgress) { objPos.setY ( (1 - forwardProgress) * (oy + oheight * objGridY) + forwardProgress * (oy + mDecorTopHeight)); if (fixedInterior) object->offsetTexCoordForQuadBefore (). setY (-forwardProgress * mWindow->height ()); } else { objPos.setY (oy + mDecorTopHeight); if (!fixedInterior) object->offsetTexCoordForQuadAfter (). setY ((forwardProgress - relPosInWinContents) * mWindow->height ()); } } } else // object is at the right side { // Set y position to the y position of the object at the left // on the same row (previous object) objPos.setY ((object - 1)->position ().y ()); // Also copy offset texture y coordinates object->offsetTexCoordForQuadBefore (). setY ((object - 1)->offsetTexCoordForQuadBefore ().y ()); object->offsetTexCoordForQuadAfter (). setY ((object - 1)->offsetTexCoordForQuadAfter ().y ()); } float origx = ox + owidth * object->gridPosition ().x (); objPos.setX (origx); } }
int OutputDevices::outputDeviceForGeometry ( const CompWindow::Geometry& gm, int strategy, CompSize* screen) const { int overlapAreas[outputDevs.size ()]; int highest, seen, highestScore; int x, y; unsigned int i; CompRect geomRect; if (outputDevs.size () == 1) return 0; if (strategy == CoreOptions::OverlappingOutputsSmartMode) { /* We're only going to use geomRect for overlapping area calculations, so the window rectangle is enough. We don't need to consider anything more like the border because it will never be significant to the result */ geomRect = gm; } else { /* for biggest/smallest modes, only use the window center to determine the correct output device */ x = (gm.x () + (gm.width () / 2) + gm.border ()) % screen->width (); if (x < 0) x += screen->width (); y = (gm.y () + (gm.height () / 2) + gm.border ()) % screen->height (); if (y < 0) y += screen->height (); geomRect.setGeometry (x, y, 1, 1); } /* get amount of overlap on all output devices */ for (i = 0; i < outputDevs.size (); i++) { CompRect overlap = outputDevs[i] & geomRect; overlapAreas[i] = overlap.area (); } /* find output with largest overlap */ for (i = 0, highest = 0, highestScore = 0; i < outputDevs.size (); i++) { if (overlapAreas[i] > highestScore) { highest = i; highestScore = overlapAreas[i]; } } /* look if the highest score is unique */ for (i = 0, seen = 0; i < outputDevs.size (); i++) if (overlapAreas[i] == highestScore) seen++; if (seen > 1) { /* it's not unique, select one output of the matching ones and use the user preferred strategy for that */ unsigned int currentSize, bestOutputSize; bool searchLargest; searchLargest = (strategy != CoreOptions::OverlappingOutputsPreferSmallerOutput); if (searchLargest) bestOutputSize = 0; else bestOutputSize = UINT_MAX; for (i = 0, highest = 0; i < outputDevs.size (); i++) if (overlapAreas[i] == highestScore) { bool bestFit; currentSize = outputDevs[i].area (); if (searchLargest) bestFit = (currentSize > bestOutputSize); else bestFit = (currentSize < bestOutputSize); if (bestFit) { highest = i; bestOutputSize = currentSize; } } } return highest; }
void GhostAnim::step () { float t = 1. - progressLinear (); if (mCurWindowEvent == WindowEventClose) t = 1. - t; CompRect winRect (mAWindow->savedRectsValid () ? mAWindow->saveWinRect () : mWindow->geometry ()); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); CompWindowExtents outExtents (mAWindow->savedRectsValid () ? mAWindow->savedOutExtents () : mWindow->output ()); int wx = winRect.x (); int wy = winRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); AnimJCScreen *ajs = AnimJCScreen::get (screen); float waveAmp = 3 * ajs->optionGetGhostAmplitude (); float waveLengthX1 = 0.4; float waveLengthX2 = 0.3; float waveLengthY1 = 0.45; float waveLengthY2 = 0.35; float wavePositionX1 = 0.25 * t * ajs->optionGetGhostWaveSpeed (); float wavePositionX2 = -0.25 * t * ajs->optionGetGhostWaveSpeed (); float wavePositionY1 = 0.25 * t * ajs->optionGetGhostWaveSpeed (); float wavePositionY2 = -0.25 * t * ajs->optionGetGhostWaveSpeed (); GridModel::GridObject *object = mModel->objects (); unsigned int n = mModel->numObjects (); for (unsigned int i = 0; i < n; i++, object++) { Point3d &objPos = object->position (); float origx = wx + mModel->scale ().x () * (owidth * object->gridPosition ().x () - outExtents.left); float origy = wy + mModel->scale ().y () * (oheight * object->gridPosition ().y () - outExtents.top); float x = object->gridPosition ().x (); float y = object->gridPosition ().y (); float distFromWaveX1 = x - wavePositionX1; float distFromWaveX2 = x - wavePositionX2; float distFromWaveY1 = y - wavePositionY1; float distFromWaveY2 = y - wavePositionY2; objPos.setX (origx + waveAmp * sin (distFromWaveX1 / waveLengthX1 * 2 * M_PI) + waveAmp * sin (distFromWaveX2 / waveLengthX2 * 2 * M_PI)); objPos.setY (origy + waveAmp * sin (distFromWaveY1 / waveLengthY1 * 2 * M_PI) + waveAmp * sin (distFromWaveY2 / waveLengthY2 * 2 * M_PI)); objPos.setZ (0); } }
void GridAnim::addGeometry (const GLTexture::MatrixList &matrix, const CompRegion ®ion, const CompRegion &clip, unsigned int maxGridWidth, unsigned int maxGridHeight) { if (region.isEmpty ()) // nothing to do return; GLfloat *v, *vMax; bool notUsing3dCoords = !using3D (); CompRect outRect (mAWindow->savedRectsValid () ? mAWindow->savedOutRect () : mWindow->outputRect ()); CompWindowExtents outExtents (mAWindow->savedRectsValid () ? mAWindow->savedOutExtents () : mWindow->output ()); // window output (contents + decorations + shadows) coordinates and size int ox = outRect.x (); int oy = outRect.y (); int owidth = outRect.width (); int oheight = outRect.height (); // to be used if event is shade/unshade float winContentsY = oy + outExtents.top; float winContentsHeight = oheight - outExtents.top - outExtents.bottom; GLWindow *gWindow = GLWindow::get (mWindow); GLVertexBuffer *vertexBuffer = gWindow->vertexBuffer (); int vSize = vertexBuffer->getVertexStride (); // Indentation kept to provide a clean diff with the old code, for now... { int y1 = outRect.y1 (); int x2 = outRect.x2 (); int y2 = outRect.y2 (); float gridW = (float)owidth / (mGridWidth - 1); float gridH; if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { if (y1 < winContentsY) // if at top part gridH = mDecorTopHeight; else if (y2 > winContentsY + winContentsHeight) // if at bottom gridH = mDecorBottomHeight; else // in window contents (only in Y coords) { float winContentsHeight = oheight - (mDecorTopHeight + mDecorBottomHeight); gridH = winContentsHeight / (mGridHeight - 3); } } else gridH = (float)oheight / (mGridHeight - 1); int oldCount = vertexBuffer->countVertices (); gWindow->glAddGeometry (matrix, region, clip, gridW, gridH); int newCount = vertexBuffer->countVertices (); v = vertexBuffer->getVertices () + (oldCount * vSize); vMax = vertexBuffer->getVertices () + (newCount * vSize); float x, y, topiyFloat; // For each vertex for (; v < vMax; v += vSize) { x = v[0]; y = v[1]; if (y > y2) y = y2; if (mCurWindowEvent == WindowEventShade || mCurWindowEvent == WindowEventUnshade) { if (y1 < winContentsY) // if at top part { topiyFloat = (y - oy) / mDecorTopHeight; topiyFloat = MIN (topiyFloat, 0.999); // avoid 1.0 } else if (y2 > winContentsY + winContentsHeight) // if at bottom topiyFloat = (mGridHeight - 2) + (mDecorBottomHeight ? (y - winContentsY - winContentsHeight) / mDecorBottomHeight : 0); else // in window contents (only in Y coords) topiyFloat = (mGridHeight - 3) * (y - winContentsY) / winContentsHeight + 1; } else topiyFloat = (mGridHeight - 1) * (y - oy) / oheight; // topiy should be at most (mGridHeight - 2) int topiy = (int)(topiyFloat + 1e-4); if (topiy == mGridHeight - 1) --topiy; int bottomiy = topiy + 1; float iny = topiyFloat - topiy; float inyRest = 1 - iny; // End of calculations for y // Indentation kept to provide a clean diff with the old code... { if (x > x2) x = x2; // find containing grid cell (leftix rightix) x (topiy bottomiy) float leftixFloat = (mGridWidth - 1) * (x - ox) / owidth; int leftix = (int)(leftixFloat + 1e-4); if (leftix == mGridWidth - 1) --leftix; int rightix = leftix + 1; // GridModel::GridObjects that are at top, bottom, left, right corners of quad GridModel::GridObject *objToTopLeft = &(mModel->mObjects[topiy * mGridWidth + leftix]); GridModel::GridObject *objToTopRight = &(mModel->mObjects[topiy * mGridWidth + rightix]); GridModel::GridObject *objToBottomLeft = &(mModel->mObjects[bottomiy * mGridWidth + leftix]); GridModel::GridObject *objToBottomRight = &(mModel->mObjects[bottomiy * mGridWidth + rightix]); Point3d &objToTopLeftPos = objToTopLeft->mPosition; Point3d &objToTopRightPos = objToTopRight->mPosition; Point3d &objToBottomLeftPos = objToBottomLeft->mPosition; Point3d &objToBottomRightPos = objToBottomRight->mPosition; // find position in cell by taking remainder of flooring float inx = leftixFloat - leftix; float inxRest = 1 - inx; // Interpolate to find deformed coordinates float hor1x = (inxRest * objToTopLeftPos.x () + inx * objToTopRightPos.x ()); float hor1y = (inxRest * objToTopLeftPos.y () + inx * objToTopRightPos.y ()); float hor1z = (notUsing3dCoords ? 0 : inxRest * objToTopLeftPos.z () + inx * objToTopRightPos.z ()); float hor2x = (inxRest * objToBottomLeftPos.x () + inx * objToBottomRightPos.x ()); float hor2y = (inxRest * objToBottomLeftPos.y () + inx * objToBottomRightPos.y ()); float hor2z = (notUsing3dCoords ? 0 : inxRest * objToBottomLeftPos.z () + inx * objToBottomRightPos.z ()); float deformedX = inyRest * hor1x + iny * hor2x; float deformedY = inyRest * hor1y + iny * hor2y; float deformedZ = inyRest * hor1z + iny * hor2z; v[0] = deformedX; v[1] = deformedY; v[2] = deformedZ; } } } }