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; }
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; }