int GUIAPI TabbedTextOutLen (HDC hdc, int x, int y, const char* spText, int len) { PCLIPRECT pClipRect; PDC pdc; SIZE size; RECT rcOutput; if (len == 0) return 0; if (len < 0) len = strlen (spText); pdc = dc_HDC2PDC(hdc); coor_LP2SP (pdc, &pdc->CurTextPos.x, &pdc->CurTextPos.y); gdi_get_TabbedTextOut_extent (pdc, pdc->pLogFont, pdc->tabstop, spText, len, &size, &pdc->CurTextPos); coor_SP2LP (pdc, &pdc->CurTextPos.x, &pdc->CurTextPos.y); if (dc_IsGeneralHDC(hdc)) { pthread_mutex_lock (&pdc->pGCRInfo->lock); if (!dc_GenerateECRgn (pdc, FALSE)) { pthread_mutex_unlock (&pdc->pGCRInfo->lock); return size.cx; } } // Transfer logical to device to screen here. coor_LP2SP(pdc, &x, &y); rcOutput.left = x; rcOutput.top = y; rcOutput.right = x + size.cx + 1; rcOutput.bottom = y + size.cy + 1; NormalizeRect(&rcOutput); pthread_mutex_lock (&__mg_gdilock); IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); // set graphics context. GAL_SetGC(pdc->gc); pClipRect = pdc->ecrgn.head; while(pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping(pdc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); gdi_tabbedtextout (pdc, x, y, spText, len); } pClipRect = pClipRect->next; } if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(TRUE, &rcOutput); pthread_mutex_unlock(&__mg_gdilock); if (dc_IsGeneralHDC(hdc)) pthread_mutex_unlock (&pdc->pGCRInfo->lock); return size.cx; }
/* Returns TRUE if rect is at least partly inside region */ BOOL GUIAPI RectInRegion (PCLIPRGN region, const RECT* rect) { PCLIPRECT cliprect = region->head; /* check with bounding rect of clipping region */ if (!DoesIntersect (®ion->rcBound, rect)) return FALSE; /* find the ban in which this point lies */ cliprect = region->head; while (cliprect) { if (DoesIntersect (&cliprect->rc, rect)) return TRUE; cliprect = cliprect->next; } return FALSE; }
void GUIAPI BitBlt(HDC hsdc, int sx, int sy, int sw, int sh, HDC hddc, int dx, int dy, DWORD dwRop) { PCLIPRECT pClipRect; PDC psdc, pddc; RECT rcOutput; psdc = dc_HDC2PDC(hsdc); pddc = dc_HDC2PDC(hddc); if (dc_IsGeneralHDC(hddc)) { if (!dc_GenerateECRgn (pddc, FALSE)) { return; } } if (sw <= 0 || sh <= 0) { sw = RECTW (psdc->DevRC); sh = RECTH (psdc->DevRC); } // Transfer logical to device to screen here. sw += sx; sh += sy; coor_LP2SP(psdc, &sx, &sy); coor_LP2SP(psdc, &sw, &sh); (sw > sx) ? (sw -= sx) : (sw = sx - sw); (sh > sy) ? (sh -= sy) : (sh = sy - sh); coor_LP2SP(pddc, &dx, &dy); rcOutput.left = dx; rcOutput.top = dy; rcOutput.right = dx + sw; rcOutput.bottom = dy + sh; NormalizeRect(&rcOutput); ShowCursorForGDI(FALSE, &g_rcScr); // set graphics context. GAL_SetGC (pddc->gc); pClipRect = pddc->ecrgn.head; while(pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping(pddc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); GAL_CrossBlit (psdc->gc, sx, sy, sw, sh, pddc->gc, dx, dy); } pClipRect = pClipRect->next; } ShowCursorForGDI(TRUE, &g_rcScr); }
INT16U SubtractGuiRect(CGuiRect* rc, const CGuiRect* psrc1, const CGuiRect* psrc2) { CGuiRect src, rcExpect, *prcExpect; INT16U nCount = 0; src = *psrc1; rcExpect = *psrc2; prcExpect = &rcExpect; if (!DoesIntersect (&src, prcExpect)) { nCount = 1; rc[0] = src; } else { if(prcExpect->top > src.top) { rc[nCount].left = src.left; rc[nCount].top = src.top; rc[nCount].right = src.right; rc[nCount].bottom = prcExpect->top; nCount++; src.top = prcExpect->top; } if(prcExpect->bottom < src.bottom) { rc[nCount].top = prcExpect->bottom; rc[nCount].left = src.left; rc[nCount].right = src.right; rc[nCount].bottom = src.bottom; nCount++; src.bottom = prcExpect->bottom; } if(prcExpect->left > src.left) { rc[nCount].left = src.left; rc[nCount].top = src.top; rc[nCount].right = prcExpect->left; rc[nCount].bottom = src.bottom; nCount++; } if(prcExpect->right < src.right) { rc[nCount].left = prcExpect->right; rc[nCount].top = src.top; rc[nCount].right = src.right; rc[nCount].bottom = src.bottom; nCount++; } } return nCount; }
void GUIAPI Rectangle(HDC hdc, int x0, int y0, int x1, int y1) { PCLIPRECT pClipRect; PDC pdc; RECT rcOutput; pdc = dc_HDC2PDC(hdc); if (dc_IsGeneralHDC(hdc)) { pthread_mutex_lock (&pdc->pGCRInfo->lock); if (!dc_GenerateECRgn (pdc, FALSE)) { pthread_mutex_unlock (&pdc->pGCRInfo->lock); return; } } // Transfer logical to device to screen here. coor_LP2SP(pdc, &x0, &y0); coor_LP2SP(pdc, &x1, &y1); rcOutput.left = x0; rcOutput.top = y0; rcOutput.right = x1; rcOutput.bottom = y1; NormalizeRect (&rcOutput); rcOutput.right ++; rcOutput.bottom ++; pthread_mutex_lock (&__mg_gdilock); IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); // set graphics context. GAL_SetGC (pdc->gc); GAL_SetFgColor (pdc->gc, pdc->pencolor); pClipRect = pdc->ecrgn.head; while(pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping (pdc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); GAL_Rectangle (pdc->gc, x0, y0, x1, y1, pdc->pencolor); } pClipRect = pClipRect->next; } if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(TRUE, &rcOutput); pthread_mutex_unlock(&__mg_gdilock); if (dc_IsGeneralHDC(hdc)) pthread_mutex_unlock (&pdc->pGCRInfo->lock); }
int GUIAPI SubtractRect(RECT* rc, const RECT* psrc1, const RECT* psrc2) { RECT src, rcExpect, *prcExpect; int nCount = 0; src = *psrc1; rcExpect = *psrc2; prcExpect = &rcExpect; if (!DoesIntersect (&src, prcExpect)) { nCount = 1; rc[0] = src; } else { if(prcExpect->top > src.top) { rc[nCount].left = src.left; rc[nCount].top = src.top; rc[nCount].right = src.right; rc[nCount].bottom = prcExpect->top; nCount++; src.top = prcExpect->top; } if(prcExpect->bottom < src.bottom) { rc[nCount].top = prcExpect->bottom; rc[nCount].left = src.left; rc[nCount].right = src.right; rc[nCount].bottom = src.bottom; nCount++; src.bottom = prcExpect->bottom; } if(prcExpect->left > src.left) { rc[nCount].left = src.left; rc[nCount].top = src.top; rc[nCount].right = prcExpect->left; rc[nCount].bottom = src.bottom; nCount++; } if(prcExpect->right < src.right) { rc[nCount].left = prcExpect->right; rc[nCount].top = src.top; rc[nCount].right = src.right; rc[nCount].bottom = src.bottom; nCount++; } } return nCount; }
/****************************** Bitmap Support *******************************/ void GUIAPI FillBox (HDC hdc, int x, int y, int w, int h) { PCLIPRECT pClipRect; PDC pdc; RECT rcOutput; pdc = dc_HDC2PDC(hdc); if (dc_IsGeneralHDC(hdc)) { if (!dc_GenerateECRgn (pdc, FALSE)) { return; } } // Transfer logical to device to screen here. w += x; h += y; coor_LP2SP(pdc, &x, &y); coor_LP2SP(pdc, &w, &h); rcOutput.left = x; rcOutput.top = y; rcOutput.right = w; rcOutput.bottom = h; NormalizeRect (&rcOutput); w = RECTW (rcOutput); h = RECTH (rcOutput); IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); // set graphics context. GAL_SetGC (pdc->gc); GAL_SetFgColor (pdc->gc, pdc->brushcolor); pClipRect = pdc->ecrgn.head; while(pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping(pdc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); GAL_FillBox (pdc->gc, x, y, w, h, pdc->brushcolor); } pClipRect = pClipRect->next; } if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(TRUE, &rcOutput); }
bool DistanceEstimator::Intersect(const Ray &r, float *tHit, float *rayEpsilon, DifferentialGeometry *dg) const { bool succeed = DoesIntersect(r, tHit); if (!succeed) return false; Ray ray; (*WorldToObject)(r, &ray); Point p = ray(*tHit); *rayEpsilon = DE_params.hitEpsilon * DE_params.rayEpsilonMultiplier; Vector n = CalculateNormal(p, DE_params.normalEpsilon); Vector DPDU, DPDV; CoordinateSystem(n, &DPDU, &DPDV); const Transform &o2w = *ObjectToWorld; *dg = DifferentialGeometry(o2w(p), o2w(DPDU), o2w(DPDV), Normal(), Normal(), 0, 0, this); return true; }
void WorldRenderer::GenerateGrass(const Vector2UINT& sectorCoords) { // Grass Turned Off if ( !zGrassDensity ) { return; } // Delete previous grass if existing. auto grassIterator = this->zGrass.find(sectorCoords); // Create Sector Rect Rect sectorRect; sectorRect.topLeft.x = (float)sectorCoords.x * FSECTOR_WORLD_SIZE; sectorRect.topLeft.y = (float)sectorCoords.y * FSECTOR_WORLD_SIZE; sectorRect.size.x = FSECTOR_WORLD_SIZE; sectorRect.size.y = FSECTOR_WORLD_SIZE; // Check if inside clip range Circle clipCircle(zGraphics->GetCamera()->GetPosition().GetXZ(), zGrassFarDistance); // Check Intersection if ( !DoesIntersect(sectorRect, clipCircle) ) { if ( grassIterator != this->zGrass.end() ) { // Remove from graphics engine. this->zGraphics->DeleteBillboardCollection(grassIterator->second); // Remove from map. this->zGrass.erase(grassIterator); } return; } // Delete Old Grass if( grassIterator != this->zGrass.end() ) { // Remove from graphics engine. this->zGraphics->DeleteBillboardCollection(grassIterator->second); // Reset grassIterator->second = 0; } // First check if the sector has any grass texture Sector* sector = this->zWorld->GetSector(sectorCoords); bool found = false; for(unsigned int i = 0; i < SECTOR_BLEND_CHANNELS && !found; ++i) { if(strcmp(sector->GetTextureName(i), "01_v02-Moss.png") == 0) { found = true; } else if(strcmp(sector->GetTextureName(i), "06_v01-MossDark.png") == 0) { found = true; } else if(strcmp(sector->GetTextureName(i), "07_v01-MossLight.png") == 0) { found = true; } } // No Grass Textures Found if(!found) { return; } float width = FSECTOR_WORLD_SIZE; float depth = FSECTOR_WORLD_SIZE; unsigned int sqrtGrassDensity = (unsigned int)sqrt((long)this->zGrassDensity); float xDiff = width / sqrtGrassDensity; float zDiff = depth / sqrtGrassDensity; Vector2 grassPos = Vector2(0.0f); Vector2 terrainPosXZ = sectorRect.topLeft; float blendValueGrassLight = 0.0f; float blendValueGrassMedium = 0.0f; float blendValueGrassDark = 0.0f; float blendThreshHold = 0.32f; const static float RGB_MIN_MAX = 50.0f / 255.0f; Vector3* positions = new Vector3[this->zGrassDensity]; Vector2* sizes = new Vector2[this->zGrassDensity]; Vector3* colors = new Vector3[this->zGrassDensity]; fast_rand_seed = sectorCoords.x + sectorCoords.y; float rndMaxInv = 1.0f / (float)RAND_MAX; float grassWidth = 0.0f; float grassHeight = 0.0f; float terrainY = 0.0f; Vector2 offsetVector = Vector2(xDiff, zDiff) * 0.5f; unsigned int index = 0; float totBlendValue = 0.0f; //Values taken from average texture color. Vector3 colorGrassLight = Vector3(91.0f, 131.0f, 65.0f) / 255.0f; Vector3 colorGrassMedium = Vector3(107.0f, 142.0f, 77.0f) / 255.0f; Vector3 colorGrassDark = Vector3(68.0f, 104.0f, 45.0f) / 255.0f; Vector3 rndGrassColorOffsetVecGrassLight = Vector3(0.0f, 0.0f, 0.0f); Vector3 rndGrassColorOffsetVecGrassMedium = Vector3(0.0f, 0.0f, 0.0f); Vector3 rndGrassColorOffsetVecGrassDark = Vector3(0.0f, 0.0f, 0.0f); float minMaxDistX = xDiff * 0.5f - zGrassNeightbourDistance * 0.5f; float minMaxDistZ = zDiff * 0.5f - zGrassNeightbourDistance * 0.5f; for(unsigned int x = 0; x < sqrtGrassDensity; ++x) { for(unsigned int z = 0; z < sqrtGrassDensity; ++z) { // Initial position grassPos = terrainPosXZ + Vector2((float)x * xDiff, (float)z * zDiff) + offsetVector; // Move initial position randomly grassPos.x += fastrand() * rndMaxInv * 2.0f * minMaxDistX - minMaxDistX; grassPos.y += fastrand() * rndMaxInv * 2.0f * minMaxDistZ - minMaxDistZ; // Randomize Size grassWidth = fastrand() * rndMaxInv * (zGrassWidthMax-zGrassWidthMin) + zGrassWidthMin; grassHeight = fastrand() * rndMaxInv * (zGrassHeightMax-zGrassHeightMin) + zGrassHeightMin; // Randomize dark grass RGB = rgb[-RGB_MIN_MAX, 0] rndGrassColorOffsetVecGrassDark.y = fastrand() * rndMaxInv * RGB_MIN_MAX - RGB_MIN_MAX; // Randomize medium grass RGB = rgb[-RGB_MIN_MAX / 2, RGB_MIN_MAX / 2] rndGrassColorOffsetVecGrassMedium.y = (fastrand() * rndMaxInv * 2.0f * RGB_MIN_MAX - RGB_MIN_MAX)*0.5f; // Randomize light grass RGB = rgb[0, RGB_MIN_MAX] rndGrassColorOffsetVecGrassLight.y = fastrand() * rndMaxInv * RGB_MIN_MAX; try { terrainY = zWorld->CalcHeightAtWorldPos(grassPos); } catch (...) { continue; } //blendValueGrassLight + blendValueGrassMedium + blendValueGrassDark -> range[0,1] blendValueGrassLight = this->zWorld->GetAmountOfTexture(grassPos, "07_v01-MossLight.png"); blendValueGrassMedium = this->zWorld->GetAmountOfTexture(grassPos, "01_v02-Moss.png"); blendValueGrassDark = this->zWorld->GetAmountOfTexture(grassPos, "06_v01-MossDark.png"); totBlendValue = blendValueGrassLight + blendValueGrassMedium + blendValueGrassDark; if(totBlendValue > blendThreshHold) { //totBlendValue range[blendThreshHold, 1], we want [0,1] float tmp = totBlendValue - blendThreshHold; //range[0, 1 - blendThreshHold]; tmp /= 1.0f - blendThreshHold; totBlendValue = tmp; //Set size grassHeight *= totBlendValue; //modify grass height depending on blend values //If it is below minGrassHeight, don't add it. (It can never be greater than maxHeight) if(grassHeight >= zGrassHeightMin) { sizes[index] = Vector2(grassWidth, grassHeight); //Set position positions[index] = Vector3(grassPos.x, terrainY + grassHeight * 0.5f, grassPos.y); //Set color Vector3 test = (colorGrassLight + rndGrassColorOffsetVecGrassLight) * blendValueGrassLight + (colorGrassMedium + rndGrassColorOffsetVecGrassMedium) * blendValueGrassMedium + (colorGrassDark + rndGrassColorOffsetVecGrassDark) * blendValueGrassDark + Vector3(1.0f, 1.0f, 1.0f) //Color is a multiplier. - Vector3(0.8f, 0.8f, 0.8f); //Adjust ambient & diffuse TTILLMAN colors[index] = test; //Increase index(number of grass objects) index++; } } } } //Add grass //No offset vector needed since grass positions is in world space. if(index > 0) { this->zGrass[sectorCoords] = this->zGraphics->CreateBillboardCollection(index, positions, sizes, colors, Vector3(0.0f, 0.0f, 0.0f), "Media/Grass.png"); this->zGrass[sectorCoords]->SetRenderShadowFlag(false); //Don't render shadows. this->zGrass[sectorCoords]->SetCullFarDistance(zGrassFarDistance); this->zGrass[sectorCoords]->SetCullNearDistance(zGrassNearDistance); } //Delete data delete [] positions; delete [] sizes; delete [] colors; }
void GUIAPI FocusRect(HDC hdc, int x0, int y0, int x1, int y1) { PCLIPRECT pClipRect; PDC pdc; int l, t, r, b, w, h; RECT rcOutput; size_t sizeh, sizev; BYTE* vbuff = NULL; BYTE* hline1 = NULL, * hline2 = NULL; BYTE* vline1 = NULL, * vline2 = NULL; int bpp; BYTE xor_byte; pdc = dc_HDC2PDC(hdc); bpp = GAL_BytesPerPixel (pdc->gc); if (GAL_BitsPerPixel (pdc->gc) < 8) xor_byte = 0x0F; else xor_byte = 0xFF; if (dc_IsGeneralHDC(hdc)) { pthread_mutex_lock (&pdc->pGCRInfo->lock); if (!dc_GenerateECRgn (pdc, FALSE)) { pthread_mutex_unlock (&pdc->pGCRInfo->lock); return; } } // Transfer logical to device to screen here. coor_LP2SP(pdc, &x0, &y0); coor_LP2SP(pdc, &x1, &y1); l = MIN (x0, x1); t = MIN (y0, y1); r = MAX (x0, x1); b = MAX (y0, y1); rcOutput.left = l; rcOutput.top = t; rcOutput.right = r + 1; rcOutput.bottom = b + 1; pthread_mutex_lock (&__mg_gdilock); IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); GAL_SetGC (pdc->gc); w = r - l + 1; h = b - t - 1; if (w == 0 || h == 0) goto my_exit; sizeh = w * bpp; sizev = h * bpp; #ifdef HAVE_ALLOCA if (!(vbuff = alloca ((sizeh << 1) + (sizev << 1)))) #else if (!(vbuff = malloc ((sizeh << 1) + (sizev << 1)))) #endif goto my_exit; if (w > 0) { int i, j; int offset; hline1 = vbuff; hline2 = vbuff + sizeh; GAL_GetBox (pdc->gc, l, t, w, 1, hline1); GAL_GetBox (pdc->gc, l, b, w, 1, hline2); offset = 0; for (i = 0; i < w; i += 2) { for (j = 0; j < bpp; j++) { hline1[offset + j] ^= xor_byte; hline2[offset + j] ^= xor_byte; } offset += bpp << 1; } } if (h > 0) { int i, j, offset; vline1 = vbuff + (sizeh << 1); vline2 = vbuff + (sizeh << 1) + sizev; GAL_GetBox (pdc->gc, l, t + 1, 1, h, vline1); GAL_GetBox (pdc->gc, r, t + 1, 1, h, vline2); offset = 0; for (i = 0; i < h; i += 2) { for (j = 0; j < bpp; j++) { vline1[offset + j] ^= xor_byte; vline2[offset + j] ^= xor_byte; } offset += bpp << 1; } } // set graphics context. GAL_SetGC (pdc->gc); pClipRect = pdc->ecrgn.head; while(pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping(pdc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); if (hline1) { GAL_PutBox (pdc->gc, l, t, w, 1, hline1); GAL_PutBox (pdc->gc, l, b, w, 1, hline2); } if (vline1) { GAL_PutBox (pdc->gc, l, t + 1, 1, h, vline1); GAL_PutBox (pdc->gc, r, t + 1, 1, h, vline2); } } pClipRect = pClipRect->next; } my_exit: if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(TRUE, &rcOutput); pthread_mutex_unlock (&__mg_gdilock); if (dc_IsGeneralHDC(hdc)) pthread_mutex_unlock (&pdc->pGCRInfo->lock); #ifndef HAVE_ALLOCA free (vbuff); #endif }
void GUIAPI LineTo (HDC hdc, int x, int y) { PCLIPRECT pClipRect; PDC pdc; RECT rcOutput; int startx, starty; pdc = dc_HDC2PDC(hdc); startx = pdc->CurPenPos.x; starty = pdc->CurPenPos.y; // Move the current pen pos. pdc->CurPenPos.x = x; pdc->CurPenPos.y = y; if (dc_IsGeneralHDC(hdc)) { pthread_mutex_lock (&pdc->pGCRInfo->lock); if (!dc_GenerateECRgn (pdc, FALSE)) { pthread_mutex_unlock (&pdc->pGCRInfo->lock); return; } } // Transfer logical to device to screen here. coor_LP2SP(pdc, &x, &y); coor_LP2SP(pdc, &startx, &starty); rcOutput.left = startx; rcOutput.top = starty; rcOutput.right = x; rcOutput.bottom = y; NormalizeRect (&rcOutput); InflateRect (&rcOutput, 1, 1); pthread_mutex_lock (&__mg_gdilock); IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); // set graphics context. GAL_SetGC (pdc->gc); GAL_SetFgColor (pdc->gc, pdc->pencolor); pClipRect = pdc->ecrgn.head; while(pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping (pdc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); if(starty == y) { if (startx > x) GAL_DrawHLine (pdc->gc, x, y, startx - x, pdc->pencolor); else GAL_DrawHLine (pdc->gc, startx, y, x - startx, pdc->pencolor); } else GAL_Line (pdc->gc, startx, starty, x, y, pdc->pencolor); } pClipRect = pClipRect->next; } if (!dc_IsMemHDC (hdc)) ShowCursorForGDI (TRUE, &rcOutput); pthread_mutex_unlock (&__mg_gdilock); if (dc_IsGeneralHDC(hdc)) pthread_mutex_unlock (&pdc->pGCRInfo->lock); }
bool DistanceEstimator::IntersectP(const Ray &r) const { return DoesIntersect(r, NULL); }
void GUIAPI StretchBlt (HDC hsdc, int sx, int sy, int sw, int sh, HDC hddc, int dx, int dy, int dw, int dh, DWORD dwRop) { PCLIPRECT pClipRect; PDC psdc, pddc; void* srcBitmap = NULL; void* scaledBitmap = NULL; RECT rcOutput; psdc = dc_HDC2PDC(hsdc); pddc = dc_HDC2PDC(hddc); if (dc_IsGeneralHDC(hddc)) { if (!dc_GenerateECRgn (pddc, FALSE)) { return; } } // Transfer logical to device to screen here. sw += sx; sh += sy; coor_LP2SP(psdc, &sx, &sy); coor_LP2SP(psdc, &sw, &sh); (sw > sx) ? (sw -= sx) : (sw = sx - sw); (sh > sy) ? (sh -= sy) : (sh = sy - sh); dw += dx; dh += dy; coor_LP2SP(pddc, &dx, &dy); coor_LP2SP(pddc, &dw, &dh); rcOutput.left = dx; rcOutput.top = dy; rcOutput.right = dw; rcOutput.bottom = dh; NormalizeRect (&rcOutput); dw -= dx; dh -= dy; if (!dc_IsMemHDC(hddc)) ShowCursorForGDI(FALSE, &g_rcScr); GAL_SetGC (psdc->gc); if ((srcBitmap = malloc (GAL_BoxSize (psdc->gc, sw, sh))) == NULL || (scaledBitmap = malloc (GAL_BoxSize (pddc->gc, dw, dh))) == NULL) goto free_ret; GAL_GetBox (psdc->gc, sx, sy, sw, sh, srcBitmap); GAL_ScaleBox (psdc->gc, sw, sh, srcBitmap, dw, dh, scaledBitmap); GAL_SetGC (pddc->gc); pClipRect = pddc->ecrgn.head; while(pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping (pddc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); GAL_PutBox (pddc->gc, dx, dy, dw, dh, scaledBitmap); } pClipRect = pClipRect->next; } free_ret: if (!dc_IsMemHDC(hddc)) ShowCursorForGDI (TRUE, &g_rcScr); free (srcBitmap); free (scaledBitmap); }
BOOL GUIAPI FillBoxWithBitmapPart (HDC hdc, int x, int y, int w, int h, int bw, int bh, const BITMAP* pBitmap, int xo, int yo) { PCLIPRECT pClipRect; PDC pdc; void* scaledBitmap = NULL; void* partBitmap = NULL; int sw = pBitmap->bmWidth, sh = pBitmap->bmHeight; RECT rcOutput; int bpp; if (pBitmap->bmWidth <= 0 || pBitmap->bmHeight <= 0 || pBitmap->bmBits == NULL) return FALSE; pdc = dc_HDC2PDC(hdc); bpp = GAL_BytesPerPixel (pdc->gc); if (dc_IsGeneralHDC(hdc)) { if (!dc_GenerateECRgn (pdc, FALSE)) { return TRUE; } } // Transfer logical to device to screen here. w += x; h += y; coor_LP2SP(pdc, &x, &y); coor_LP2SP(pdc, &w, &h); rcOutput.left = x; rcOutput.top = y; rcOutput.right = w; rcOutput.bottom = h; NormalizeRect (&rcOutput); w = RECTW (rcOutput); h = RECTH (rcOutput); IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); // set graphics context. GAL_SetGC(pdc->gc); if (bw <= 0 || bh <= 0) { scaledBitmap = pBitmap->bmBits; bw = sw; bh = sh; } else if (bw == sw && bh == sh) scaledBitmap = pBitmap->bmBits; else { if ((scaledBitmap = malloc (GAL_BoxSize(pdc->gc, w, h))) == NULL) goto free_ret; GAL_ScaleBox (pdc->gc, sw, sh, pBitmap->bmBits, bw, bh, scaledBitmap); } // extract part box if ((partBitmap = malloc (GAL_BoxSize(pdc->gc, w, h))) == NULL) goto free_ret; bmpGetBoxPart (bpp, w, h, partBitmap, bw, bh, scaledBitmap, xo, yo); pClipRect = pdc->ecrgn.head; while(pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping(pdc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); if (pBitmap->bmType != BMP_TYPE_COLORKEY) GAL_PutBox (pdc->gc, x, y, w, h, partBitmap); else GAL_PutBoxMask (pdc->gc, x, y, w, h, partBitmap, pBitmap->bmColorKey); } pClipRect = pClipRect->next; } free_ret: if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(TRUE, &rcOutput); if (bw != sw || bh != sh) free (scaledBitmap); free (partBitmap); return TRUE; }
void GUIAPI DrawIcon(HDC hdc, int x, int y, int w, int h, HICON hicon) { PCLIPRECT pClipRect; PDC pdc; PICON picon = (PICON)hicon; int i; int imagesize; BYTE* iconimage; BYTE* andbits = NULL; BYTE* xorbits = NULL; RECT rcOutput; pdc = dc_HDC2PDC(hdc); if (dc_IsGeneralHDC(hdc)) { if (!dc_GenerateECRgn (pdc, FALSE)) { return; } } if(w <= 0) w = picon->width; if(h <= 0) h = picon->height; // Transfer logical to device to screen here. w += x; h += y; coor_LP2SP(pdc, &x, &y); coor_LP2SP(pdc, &w, &h); rcOutput.left = x; rcOutput.top = y; rcOutput.right = w; rcOutput.bottom = h; NormalizeRect (&rcOutput); w = RECTW (rcOutput); h = RECTH (rcOutput); IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); GAL_SetGC (pdc->gc); imagesize = w * h * GAL_BytesPerPixel (pdc->gc); if ((iconimage = malloc (imagesize)) == NULL) goto free_ret; if (w != picon->width || h != picon->height) { andbits = malloc (imagesize); xorbits = malloc (imagesize); if (andbits == NULL || xorbits == NULL) goto free_ret; GAL_ScaleBox (pdc->gc, picon->width, picon->height, picon->AndBits, w, h, andbits); GAL_ScaleBox (pdc->gc, picon->width, picon->height, picon->XorBits, w, h, xorbits); } else { andbits = picon->AndBits; xorbits = picon->XorBits; } GAL_GetBox (pdc->gc, x, y, w, h, iconimage); for(i = 0; i < imagesize; i++) { iconimage[i] &= andbits [i]; iconimage[i] ^= xorbits [i]; } pClipRect = pdc->ecrgn.head; while (pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping(pdc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); GAL_PutBox(pdc->gc, x, y, w, h, iconimage); } pClipRect = pClipRect->next; } free_ret: if (!dc_IsMemHDC(hdc)) ShowCursorForGDI (TRUE, &rcOutput); free (iconimage); if (w != picon->width || h != picon->height) { free (andbits); free (xorbits); } }
BOOL GUIAPI SubtractClipRect (PCLIPRGN pRgn, const RECT* pRect) { PCLIPRECT pCRect, pSaved, pTemp; RECT rc[4], rcTemp, rcInflated; int nCount; PRECT src, erc; int i; if (IsRectEmpty (pRect)) return FALSE; rcInflated = *pRect; erc = &rcInflated; NormalizeRect (erc); if (!DoesIntersect(&pRgn->rcBound, erc)) { return FALSE; } pCRect = pRgn->head; while (pCRect) { src = &pCRect->rc; if (!IntersectRect(&rcTemp, src, erc)) { pCRect = pCRect->next; continue; } pSaved = pCRect->next; nCount = 0; if(erc->top > src->top) { rc[nCount].left = src->left; rc[nCount].top = src->top; rc[nCount].right = src->right; rc[nCount].bottom = erc->top; nCount++; src->top = erc->top; } if(erc->bottom < src->bottom) { rc[nCount].top = erc->bottom; rc[nCount].left = src->left; rc[nCount].right = src->right; rc[nCount].bottom = src->bottom; nCount++; src->bottom = erc->bottom; } if(erc->left > src->left) { rc[nCount].left = src->left; rc[nCount].top = src->top; rc[nCount].right = erc->left; rc[nCount].bottom = src->bottom; nCount++; } if(erc->right < src->right) { rc[nCount].left = erc->right; rc[nCount].top = src->top; rc[nCount].right = src->right; rc[nCount].bottom = src->bottom; nCount++; } if (nCount == 0) SetRectEmpty (&pCRect->rc); else if(nCount > 0) pCRect->rc = rc[0]; for(i = 1; i<nCount; i++) { pTemp = ClipRectAlloc (pRgn->heap); pTemp->rc = rc[i]; pCRect->next = pTemp; pCRect = pTemp; } pCRect->next = pSaved; pCRect = pSaved; } EvaluateBoundRect (pRgn); return TRUE; }