void ListboxWrappedTextItem::draw(RenderCache& cache,const Rect& targetRect, float zBase, float alpha, const Rect* clipper) const { if (d_selected && d_selectBrush != 0) { cache.cacheImage(*d_selectBrush, targetRect, zBase, getModulateAlphaColourRect(d_selectCols, alpha), clipper); } Font* font = const_cast<Font*>(getFont()); if (font) { float left_offset = 0; if (d_draw_bullet) { left_offset = font->getTextExtent(ds_bullet); } Rect finalPos = targetRect; finalPos.d_top -= (font->getLineSpacing() - font->getBaseline()) * 0.5f; cache.cacheText(ds_bullet, font, d_textFormatting, finalPos, zBase, getModulateAlphaColourRect(d_textCols, alpha), clipper); finalPos.d_left += left_offset; cache.cacheText(d_itemText, font, d_textFormatting, finalPos, zBase, getModulateAlphaColourRect(d_textCols, alpha), clipper); } }
DWORD WINAPI RenderCache::RenderCacheThread(LPVOID data) { RenderCache *cache = (RenderCache *)data; PageRenderRequest req; RenderedBitmap * bmp; for (;;) { if (cache->ClearCurrentRequest()) { DWORD waitResult = WaitForSingleObject(cache->startRendering, INFINITE); // Is it not a page render request? if (WAIT_OBJECT_0 != waitResult) continue; } if (!cache->GetNextRequest(&req)) continue; if (!req.dm->PageVisibleNearby(req.pageNo) && !req.renderCb) continue; if (req.dm->dontRenderFlag) { if (req.renderCb) req.renderCb->Callback(); continue; } // make sure that we have extracted page text for // all rendered pages to allow text selection and // searching without any further delays if (!req.dm->textCache->HasData(req.pageNo)) req.dm->textCache->GetData(req.pageNo); CrashIf(req.abortCookie != NULL); bmp = req.dm->engine->RenderBitmap(req.pageNo, req.zoom, req.rotation, &req.pageRect, Target_View, &req.abortCookie); if (req.abort) { delete bmp; if (req.renderCb) req.renderCb->Callback(); continue; } if (req.renderCb) { // the callback must free the RenderedBitmap req.renderCb->Callback(bmp); req.renderCb = (RenderingCallback *)1; // will crash if accessed again, which should not happen } else { // don't replace colors for individual images if (bmp && !req.dm->engine->IsImageCollection()) UpdateBitmapColorRange(bmp->GetBitmap(), cache->colorRange); cache->Add(req, bmp); #ifdef CONSERVE_MEMORY cache->FreeNotVisible(); #endif req.dm->RepaintDisplay(); } } return 0; }
void ListboxImageItem::draw(RenderCache& cache,const Rect& targetRect, float zBase, float alpha, const Rect* clipper) const { if (d_selected && d_selectBrush != 0) { cache.cacheImage(*d_selectBrush, targetRect, zBase, getModulateAlphaColourRect(d_selectCols, alpha), clipper); } if (d_image != NULL) { cache.cacheImage(*d_image, targetRect, zBase, ColourRect(colour(1,1,1,alpha)), clipper); } }
void StressTest::OnTimer() { KillTimer(win->hwndFrame, DIR_STRESS_TIMER_ID); if (!win->dm || !win->dm->engine) return; // chm documents aren't rendered and we block until we show them // so we can assume previous page has been shown and go to next page if (win->dm->AsChmEngine()) { if (!GoToNextPage()) return; goto Next; } // For non-image files, we detect if a page was rendered by checking the cache // (but we don't wait more than 3 seconds). // Image files are always fully rendered in WM_PAINT, so we know the page // has already been rendered. bool didRender = renderCache->Exists(win->dm, currPage, win->dm->Rotation()); if (!didRender && DoCachePageRendering(win, currPage)) { double timeInMs = currPageRenderTime.GetTimeInMs(); if (timeInMs > 3.0 * 1000) { if (!GoToNextPage()) return; } } else { if (!GoToNextPage()) return; } Next: MakeRandomSelection(win->dm, currPage); TickTimer(); }
void ListboxNumberItem::draw(RenderCache& cache,const Rect& targetRect, float zBase, float alpha, const Rect* clipper) const { if (d_selected && d_selectBrush != 0) { cache.cacheImage(*d_selectBrush, targetRect, zBase, getModulateAlphaColourRect(d_selectCols, alpha), clipper); } const Font* font = getFont(); if (font) { Rect finalPos(targetRect); finalPos.d_top -= (font->getLineSpacing() - font->getBaseline()) * 0.5f; cache.cacheText(d_itemText, font, LeftAligned, finalPos, zBase, getModulateAlphaColourRect(d_textCols, alpha), clipper); } }
void ListboxTextItem::draw(RenderCache& cache,const Rect& targetRect, float zBase, float alpha, const Rect* clipper) const { if (d_selected && d_selectBrush != 0) { cache.cacheImage(*d_selectBrush, targetRect, zBase, getModulateAlphaColourRect(d_selectCols, alpha), clipper); } const FontBase* font = getFont(); if (font) { Rect finalPos(targetRect); finalPos.d_top += PixelAligned( FontBase::LineSpace * 0.5f); cache.cacheText( getOwnerWindow(), d_itemText, font, d_horzFormateing, finalPos, zBase, getModulateAlphaColourRect(d_textCols, alpha), clipper); } }
void StressTest::OnTimer(int timerIdGot) { CrashIf(timerId != timerIdGot); KillTimer(win->hwndFrame, timerId); if (!win->IsDocLoaded()) { if (!GoToNextFile()) { Finished(true); return; } TickTimer(); return; } // chm documents aren't rendered and we block until we show them // so we can assume previous page has been shown and go to next page if (!win->AsFixed()) { if (!GoToNextPage()) return; goto Next; } // For non-image files, we detect if a page was rendered by checking the cache // (but we don't wait more than 3 seconds). // Image files are always fully rendered in WM_PAINT, so we know the page // has already been rendered. DisplayModel *dm = win->AsFixed(); bool didRender = renderCache->Exists(dm, currPage, dm->GetRotation()); if (!didRender && dm->ShouldCacheRendering(currPage)) { double timeInMs = currPageRenderTime.GetTimeInMs(); if (timeInMs > 3.0 * 1000) { if (!GoToNextPage()) return; } } else if (!GoToNextPage()) { return; } MakeRandomSelection(win, currPage); Next: TickTimer(); }
void RenderableFrame::draw_impl(RenderCache& renderCache) const { // TODO: This is a fairly substantial Cut, paste, and hack job. // TODO: There are probably a thousand ways that this should be improved! Rect destArea; Vector3 final_pos(0,0,0); float org_width = d_area.getWidth(), org_height = d_area.getHeight(); Size final_size; ColourRect final_colours(d_colours); bool calcColoursPerImage = !(d_useColoursPerImage || d_colours.isMonochromatic()); float leftfactor, rightfactor, topfactor, bottomfactor; // calculate 'adjustments' required to accommodate corner pieces. float coord_adj, size_adj; // draw top-edge, if required if (d_top != NULL) { // calculate adjustments required if top-left corner will be rendered. if (d_topleft != NULL) { size_adj = (d_topleft->getWidth() - d_topleft->getOffsetX()); coord_adj = d_topleft->getWidth(); } else { coord_adj = 0; size_adj = 0; } // calculate adjustments required if top-right corner will be rendered. if (d_topright != NULL) { size_adj += (d_topright->getWidth() + d_topright->getOffsetX()); } final_size.d_width = org_width - size_adj; final_size.d_height = d_top->getHeight(); final_pos.d_x = coord_adj; final_pos.d_y = 0; // calculate final colours that are to be used if (calcColoursPerImage) { leftfactor = (final_pos.d_x + d_top->getOffsetX()) / org_width; rightfactor = leftfactor + final_size.d_width / org_width; topfactor = (final_pos.d_y + d_top->getOffsetY()) / org_height; bottomfactor = topfactor + final_size.d_height / org_height; final_colours = d_colours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor); } destArea.d_left = final_pos.d_x; destArea.d_top = final_pos.d_y; destArea.d_right = final_pos.d_x + final_size.d_width; destArea.d_bottom = final_pos.d_y + final_size.d_height; renderCache.cacheImage(*d_top, destArea, 0, final_colours); } // draw bottom-edge, if required if (d_bottom != NULL) { // calculate adjustments required if bottom-left corner will be rendered. if (d_bottomleft != NULL) { size_adj = (d_bottomleft->getWidth() - d_bottomleft->getOffsetX()); coord_adj = d_bottomleft->getWidth(); } else { coord_adj = 0; size_adj = 0; } // calculate adjustments required if bottom-right corner will be rendered. if (d_bottomright != NULL) { size_adj += (d_bottomright->getWidth() + d_bottomright->getOffsetX()); } final_size.d_width = org_width - size_adj; final_size.d_height = d_bottom->getHeight(); final_pos.d_x = coord_adj; final_pos.d_y = org_height - final_size.d_height; // calculate final colours that are to be used if (calcColoursPerImage) { leftfactor = (final_pos.d_x + d_bottom->getOffsetX()) / org_width; rightfactor = leftfactor + final_size.d_width / org_width; topfactor = (final_pos.d_y + d_bottom->getOffsetY()) / org_height; bottomfactor = topfactor + final_size.d_height / org_height; final_colours = d_colours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor); } destArea.d_left = final_pos.d_x; destArea.d_top = final_pos.d_y; destArea.d_right = final_pos.d_x + final_size.d_width; destArea.d_bottom = final_pos.d_y + final_size.d_height; renderCache.cacheImage(*d_bottom, destArea, 0, final_colours); } // draw left-edge, if required if (d_left != NULL) { // calculate adjustments required if top-left corner will be rendered. if (d_topleft != NULL) { size_adj = (d_topleft->getHeight() - d_topleft->getOffsetY()); coord_adj = d_topleft->getHeight(); } else { coord_adj = 0; size_adj = 0; } // calculate adjustments required if bottom-left corner will be rendered. if (d_bottomleft != NULL) { size_adj += (d_bottomleft->getHeight() + d_bottomleft->getOffsetY()); } final_size.d_height = org_height - size_adj; final_size.d_width = d_left->getWidth(); final_pos.d_y = coord_adj; final_pos.d_x = 0; // calculate final colours that are to be used if (calcColoursPerImage) { leftfactor = (final_pos.d_x + d_left->getOffsetX()) / org_width; rightfactor = leftfactor + final_size.d_width / org_width; topfactor = (final_pos.d_y + d_left->getOffsetY()) / org_height; bottomfactor = topfactor + final_size.d_height / org_height; final_colours = d_colours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor); } destArea.d_left = final_pos.d_x; destArea.d_top = final_pos.d_y; destArea.d_right = final_pos.d_x + final_size.d_width; destArea.d_bottom = final_pos.d_y + final_size.d_height; renderCache.cacheImage(*d_left, destArea, 0, final_colours); } // draw right-edge, if required if (d_right != NULL) { // calculate adjustments required if top-left corner will be rendered. if (d_topright != NULL) { size_adj = (d_topright->getHeight() - d_topright->getOffsetY()); coord_adj = d_topright->getHeight(); } else { coord_adj = 0; size_adj = 0; } // calculate adjustments required if bottom-left corner will be rendered. if (d_bottomright != NULL) { size_adj += (d_bottomright->getHeight() + d_bottomright->getOffsetY()); } final_size.d_height = org_height - size_adj; final_size.d_width = d_right->getWidth(); final_pos.d_y = coord_adj; final_pos.d_x = org_width - final_size.d_width; // calculate final colours that are to be used if (calcColoursPerImage) { leftfactor = (final_pos.d_x + d_right->getOffsetX()) / org_width; rightfactor = leftfactor + final_size.d_width / org_width; topfactor = (final_pos.d_y + d_right->getOffsetY()) / org_height; bottomfactor = topfactor + final_size.d_height / org_height; final_colours = d_colours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor); } destArea.d_left = final_pos.d_x; destArea.d_top = final_pos.d_y; destArea.d_right = final_pos.d_x + final_size.d_width; destArea.d_bottom = final_pos.d_y + final_size.d_height; renderCache.cacheImage(*d_right, destArea, 0, final_colours); } // draw required corner pieces... if (d_topleft != NULL) { // calculate final colours that are to be used if (calcColoursPerImage) { leftfactor = d_topleft->getOffsetX() / org_width; rightfactor = leftfactor + d_topleft->getWidth() / org_width; topfactor = d_topleft->getOffsetY() / org_height; bottomfactor = topfactor + d_topleft->getHeight() / org_height; final_colours = d_colours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor); } destArea.d_left = 0; destArea.d_top = 0; destArea.d_right = d_topleft->getWidth(); destArea.d_bottom = d_topleft->getHeight(); renderCache.cacheImage(*d_topleft, destArea, 0, final_colours); } if (d_topright != NULL) { final_pos.d_x = org_width - d_topright->getWidth(); final_pos.d_y = 0; // calculate final colours that are to be used if (calcColoursPerImage) { leftfactor = (final_pos.d_x + d_topright->getOffsetX()) / org_width; rightfactor = leftfactor + d_topright->getWidth() / org_width; topfactor = (final_pos.d_y + d_topright->getOffsetY()) / org_height; bottomfactor = topfactor + d_topright->getHeight() / org_height; final_colours = d_colours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor); } destArea.d_left = final_pos.d_x; destArea.d_top = final_pos.d_y; destArea.d_right = final_pos.d_x + d_topright->getWidth(); destArea.d_bottom = final_pos.d_y + d_topright->getHeight(); renderCache.cacheImage(*d_topright, destArea, 0, final_colours); } if (d_bottomleft != NULL) { final_pos.d_x = 0; final_pos.d_y = org_height - d_bottomleft->getHeight(); // calculate final colours that are to be used if (calcColoursPerImage) { leftfactor = (final_pos.d_x + d_bottomleft->getOffsetX()) / org_width; rightfactor = leftfactor + d_bottomleft->getWidth() / org_width; topfactor = (final_pos.d_y + d_bottomleft->getOffsetY()) / org_height; bottomfactor = topfactor + d_bottomleft->getHeight() / org_height; final_colours = d_colours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor); } destArea.d_left = final_pos.d_x; destArea.d_top = final_pos.d_y; destArea.d_right = final_pos.d_x + d_bottomleft->getWidth(); destArea.d_bottom = final_pos.d_y + d_bottomleft->getHeight(); renderCache.cacheImage(*d_bottomleft, destArea, 0, final_colours); } if (d_bottomright != NULL) { final_pos.d_x = org_width - d_bottomright->getWidth(); final_pos.d_y = org_height - d_bottomright->getHeight(); // calculate final colours that are to be used if (calcColoursPerImage) { leftfactor = (final_pos.d_x + d_bottomright->getOffsetX()) / org_width; rightfactor = leftfactor + d_bottomright->getWidth() / org_width; topfactor = (final_pos.d_y + d_bottomright->getOffsetY()) / org_height; bottomfactor = topfactor + d_bottomright->getHeight() / org_height; final_colours = d_colours.getSubRectangle( leftfactor, rightfactor, topfactor, bottomfactor); } destArea.d_left = final_pos.d_x; destArea.d_top = final_pos.d_y; destArea.d_right = final_pos.d_x + d_bottomright->getWidth(); destArea.d_bottom = final_pos.d_y + d_bottomright->getHeight(); renderCache.cacheImage(*d_bottomright, destArea, 0, final_colours); } }
WPARAM Level3( HINSTANCE hInstance, int nCmdShow ) { UNIT_TEST_MESSAGE( "\n###########\n# LEVEL 3 #\n###########\n\n" ); UNIT_TEST_MESSAGE( "Window Creation\n" ); MSG msg; HWND hwnd; WNDCLASS wc; wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); wc.lpszMenuName = NULL; wc.lpszClassName = "CarbonWndClass"; if ( !RegisterClass(&wc) ) return FALSE; hwnd = CreateWindow( "CarbonWndClass" ,"Level3" ,WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU ,CW_USEDEFAULT ,CW_USEDEFAULT ,1280 ,720 ,NULL ,NULL ,hInstance ,NULL ); if ( !hwnd ) return FALSE; ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); UNIT_TEST_MESSAGE( "Carbon Engine : Initialize\n" ); MemoryManager::Initialize( frameAllocatorSize ); FileSystem::Initialize( "../../.." ); if ( ! device3d.Initialize( hInstance, hwnd ) ) { return FALSE; } if ( ! programCache.Initialize( "shaders" ) ) { device3d.Destroy(); return FALSE; } RenderCache renderCache; FullScreenQuadRenderer fsqRenderer; fsqRenderer.Initialize(); UNIT_TEST_MESSAGE( "Carbon Engine : Run\n" ); while ( 1 ) { if ( ! MessagePump( &msg ) ) break; ///////////////////////////////////////////////////////////////////////////// programCache.Update(); fsqRenderer.Render(); renderList.Draw( renderCache ); renderCache.Clear(); device3d.Swap(); MemoryManager::FrameUpdate(); ///////////////////////////////////////////////////////////////////////////// DisplayFramerate( hwnd ); } UNIT_TEST_MESSAGE( "Carbon Engine : Destroy\n" ); fsqRenderer.Destroy(); programCache.Destroy(); device3d.Destroy(); FileSystem::Destroy(); MemoryManager::Destroy(); DestroyWindow( hwnd ); UnregisterClass( "CarbonWndClass", hInstance ); return msg.wParam; }