void GuiRiverEditorCtrl::_drawRiverControlNodes( River *river, const ColorI &color ) { if ( !River::smShowSpline ) return; RectI bounds = getBounds(); GFXDrawUtil *drawer = GFX->getDrawUtil(); bool isSelected = ( river == mSelRiver ); bool isHighlighted = ( river == mHoverRiver ); for ( U32 i = 0; i < river->mNodes.size(); i++ ) { if ( false && isSelected && mSelNode == i ) continue; const Point3F &wpos = river->mNodes[i].point; Point3F spos; project( wpos, &spos ); if ( spos.z > 1.0f ) continue; Point2I posi; posi.x = spos.x; posi.y = spos.y; if ( !bounds.pointInRect( posi ) ) continue; ColorI theColor = color; Point2I nodeHalfSize = mNodeHalfSize; if ( isHighlighted && mHoverNode == i ) { //theColor = mHoverNodeColor; nodeHalfSize += Point2I(2,2); } if ( isSelected ) { if ( mSelNode == i ) { theColor.set(0,0,255); } else if ( i == 0 ) { theColor.set(0,255,0); } else if ( i == river->mNodes.size() - 1 ) { theColor.set(255,0,0); } } drawer->drawRectFill( posi - nodeHalfSize, posi + nodeHalfSize, theColor ); } }
void GuiTabBookCtrl::onRender(Point2I offset, const RectI &updateRect) { RectI tabRect = mTabRect; tabRect.point += offset; RectI pageRect = mPageRect; pageRect.point += offset; // We're so nice we'll store the old modulation before we clear it for our rendering! :) ColorI oldModulation; GFX->getDrawUtil()->getBitmapModulation( &oldModulation ); // Wipe it out GFX->getDrawUtil()->clearBitmapModulation(); Parent::onRender(offset, updateRect); // Clip to tab area RectI savedClipRect = GFX->getClipRect(); RectI clippedTabRect = tabRect; clippedTabRect.intersect( savedClipRect ); GFX->setClipRect( clippedTabRect ); // Render our tabs renderTabs( offset, tabRect ); // Restore Rect. GFX->setClipRect( savedClipRect ); // Restore old modulation GFX->getDrawUtil()->setBitmapModulation( oldModulation ); }
void Actor::ScaleTo( const RectI &rect, StretchType st ) { // width and height of rectangle float rect_width = (float) rect.GetWidth(); float rect_height = (float) rect.GetHeight(); if( rect_width < 0 ) SetRotationY( 180 ); if( rect_height < 0 ) SetRotationX( 180 ); // center of the rectangle float rect_cx = rect.left + rect_width/2; float rect_cy = rect.top + rect_height/2; // zoom fActor needed to scale the Actor to fill the rectangle float fNewZoomX = fabsf(rect_width / m_size.x); float fNewZoomY = fabsf(rect_height / m_size.y); float fNewZoom = 0.f; switch( st ) { case cover: fNewZoom = fNewZoomX>fNewZoomY ? fNewZoomX : fNewZoomY; // use larger zoom break; case fit_inside: fNewZoom = fNewZoomX>fNewZoomY ? fNewZoomY : fNewZoomX; // use smaller zoom break; } SetXY( rect_cx, rect_cy ); SetZoom( fNewZoom ); }
bool ImagesEngine::RenderPage(HDC hDC, RectI screenRect, int pageNo, float zoom, int rotation, RectD *pageRect, RenderTarget target, AbortCookie **cookie_out) { Bitmap *bmp = LoadImage(pageNo); if (!bmp) return false; RectD pageRc = pageRect ? *pageRect : PageMediabox(pageNo); RectI screen = Transform(pageRc, pageNo, zoom, rotation).Round(); Graphics g(hDC); g.SetCompositingQuality(CompositingQualityHighQuality); g.SetSmoothingMode(SmoothingModeAntiAlias); g.SetPageUnit(UnitPixel); Color white(0xFF, 0xFF, 0xFF); Rect screenR(screenRect.ToGdipRect()); g.SetClip(screenR); g.FillRectangle(&SolidBrush(white), screenR); Matrix m; GetTransform(m, pageNo, zoom, rotation); m.Translate((REAL)(screenRect.x - screen.x), (REAL)(screenRect.y - screen.y), MatrixOrderAppend); g.SetTransform(&m); RectI pageRcI = PageMediabox(pageNo).Round(); ImageAttributes imgAttrs; imgAttrs.SetWrapMode(WrapModeTileFlipXY); Status ok = g.DrawImage(bmp, pageRcI.ToGdipRect(), 0, 0, pageRcI.dx, pageRcI.dy, UnitPixel, &imgAttrs); return ok == Ok; }
static bool pointInRect(int x, int y, RectI r) { if (x >= r.left() && x <= r.right() && y >= r.top() && y <= r.bottom()) return(true); else return(false); }
static void DrawProperties(HWND hwnd, HDC hdc) { PropertiesLayout *layoutData = FindPropertyWindowByHwnd(hwnd); ScopedFont fontLeftTxt(GetSimpleFont(hdc, LEFT_TXT_FONT, LEFT_TXT_FONT_SIZE)); ScopedFont fontRightTxt(GetSimpleFont(hdc, RIGHT_TXT_FONT, RIGHT_TXT_FONT_SIZE)); HGDIOBJ origFont = SelectObject(hdc, fontLeftTxt); /* Just to remember the orig font */ SetBkMode(hdc, TRANSPARENT); ClientRect rcClient(hwnd); FillRect(hdc, &rcClient.ToRECT(), gBrushAboutBg); SetTextColor(hdc, WIN_COL_BLACK); /* render text on the left*/ SelectObject(hdc, fontLeftTxt); for (size_t i = 0; i < layoutData->Count(); i++) { PropertyEl *el = layoutData->At(i); DrawText(hdc, el->leftTxt, -1, &el->leftPos.ToRECT(), DT_RIGHT | DT_NOPREFIX); } /* render text on the right */ SelectObject(hdc, fontRightTxt); for (size_t i = 0; i < layoutData->Count(); i++) { PropertyEl *el = layoutData->At(i); RectI rc = el->rightPos; if (rc.x + rc.dx > rcClient.x + rcClient.dx - PROPERTIES_RECT_PADDING) rc.dx = rcClient.x + rcClient.dx - PROPERTIES_RECT_PADDING - rc.x; DrawText(hdc, el->rightTxt, -1, &rc.ToRECT(), DT_LEFT | DT_PATH_ELLIPSIS | DT_NOPREFIX); } SelectObject(hdc, origFont); }
void ViewerTab::setInfoBarAndViewerResolution(const RectI& rect, const RectD& canonicalRect, double par, int texIndex) { std::string formatName, infoBarName; Gui* gui = getGui(); if (!gui) { return; } GuiAppInstancePtr app = gui->getApp(); if (!app) { return; } if (!app->getProject()->getFormatNameFromRect(rect, par, &formatName)) { formatName = makeUpFormatName(rect, par); infoBarName = formatName; } else { // If the format has a name, for the info bar also add the resolution std::stringstream ss; ss << formatName; ss << ' '; ss << rect.width(); ss << 'x'; ss << rect.height(); infoBarName = ss.str(); } _imp->infoWidget[texIndex]->setResolution(QString::fromUtf8(infoBarName.c_str())); _imp->viewer->setFormat(formatName, canonicalRect, par, texIndex); }
Vec<SelectionOnPage>* SelectionOnPage::FromRectangle(DisplayModel* dm, RectI rect) { Vec<SelectionOnPage>* sel = new Vec<SelectionOnPage>(); for (int pageNo = dm->GetEngine()->PageCount(); pageNo >= 1; --pageNo) { PageInfo* pageInfo = dm->GetPageInfo(pageNo); AssertCrash(!pageInfo || 0.0 == pageInfo->visibleRatio || pageInfo->shown); if (!pageInfo || !pageInfo->shown) continue; RectI intersect = rect.Intersect(pageInfo->pageOnScreen); if (intersect.IsEmpty()) continue; /* selection intersects with a page <pageNo> on the screen */ RectD isectD = dm->CvtFromScreen(intersect, pageNo); sel->Append(SelectionOnPage(pageNo, &isectD)); } sel->Reverse(); if (sel->size() == 0) { delete sel; return nullptr; } return sel; }
static LRESULT OnPaint(HWND hwnd) { ClientRect rect(hwnd); DoubleBuffer buffer(hwnd, rect); HDC hdc = buffer.GetDC(); HBRUSH brushBg = CreateSolidBrush(COL_WINDOW_BG); HBRUSH brushWhite = GetStockBrush(WHITE_BRUSH); FillRect(hdc, &rect.ToRECT(), brushBg); PreviewBase *preview = (PreviewBase *)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (preview && preview->renderer) { int pageNo = GetScrollPos(hwnd, SB_VERT); RectD page = preview->renderer->GetPageRect(pageNo); if (!page.IsEmpty()) { rect.Inflate(-PREVIEW_MARGIN, -PREVIEW_MARGIN); float zoom = (float)min(rect.dx / page.dx, rect.dy / page.dy) - 0.001f; RectI onScreen = RectD(rect.x, rect.y, page.dx * zoom, page.dy * zoom).Round(); onScreen.Offset((rect.dx - onScreen.dx) / 2, (rect.dy - onScreen.dy) / 2); FillRect(hdc, &onScreen.ToRECT(), brushWhite); preview->renderer->Render(hdc, onScreen, pageNo, zoom); } } DeleteObject(brushBg); DeleteObject(brushWhite); PAINTSTRUCT ps; buffer.Flush(BeginPaint(hwnd, &ps)); EndPaint(hwnd, &ps); return 0; }
static void WinUtilTest() { ScopedCom comScope; { char *string = "abcde"; size_t stringSize = 5, len; ScopedComPtr<IStream> stream(CreateStreamFromData(string, stringSize)); assert(stream); char *data = (char *)GetDataFromStream(stream, &len); assert(data && stringSize == len && str::Eq(data, string)); free(data); } { WCHAR *string = L"abcde"; size_t stringSize = 10, len; ScopedComPtr<IStream> stream(CreateStreamFromData(string, stringSize)); assert(stream); WCHAR *data = (WCHAR *)GetDataFromStream(stream, &len); assert(data && stringSize == len && str::Eq(data, string)); free(data); } { RectI oneScreen = GetFullscreenRect(NULL); RectI allScreens = GetVirtualScreenRect(); assert(allScreens.Intersect(oneScreen) == oneScreen); } }
static void NotificationWndOnPaint(HWND hwnd, NotificationWnd *wnd) { PAINTSTRUCT ps; HDC hdcWnd = BeginPaint(hwnd, &ps); ClientRect rect(hwnd); DoubleBuffer buffer(hwnd, rect); HDC hdc = buffer.GetDC(); HFONT oldfnt = SelectFont(hdc, wnd->font); RECT rTmp = rect.ToRECT(); DrawFrameControl(hdc, &rTmp, DFC_BUTTON, DFCS_BUTTONPUSH); if (wnd->highlight) { SetBkMode(hdc, OPAQUE); SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); } else { SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT)); } rect.Inflate(-PADDING, -PADDING); RectI rectMsg = rect; if (wnd->hasProgress) rectMsg.dy -= PROGRESS_HEIGHT + PADDING / 2; if (wnd->hasCancel) rectMsg.dx -= 20; ScopedMem<WCHAR> text(win::GetText(hwnd)); rTmp = rectMsg.ToRECT(); DrawText(hdc, text, -1, &rTmp, DT_SINGLELINE | DT_NOPREFIX); if (wnd->hasCancel) { rTmp = GetCancelRect(hwnd).ToRECT(); DrawFrameControl(hdc, &rTmp, DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_FLAT); } if (wnd->hasProgress) { rect.dx = wnd->progressWidth; rect.y += rectMsg.dy + PADDING / 2; rect.dy = PROGRESS_HEIGHT; PaintRect(hdc, rect); rect.x += 2; rect.dx = (wnd->progressWidth - 3) * wnd->progress / 100; rect.y += 2; rect.dy -= 3; HBRUSH brush = GetStockBrush(BLACK_BRUSH); rTmp = rect.ToRECT(); FillRect(hdc, &rTmp, brush); DeleteObject(brush); } SelectFont(hdc, oldfnt); buffer.Flush(hdcWnd); EndPaint(hwnd, &ps); }
void renderFilledBorder( const RectI &bounds, const ColorI &borderColor, const ColorI &fillColor, U32 thickness ) { RectI fillBounds = bounds; fillBounds.inset( thickness, thickness ); GFX->getDrawUtil()->drawRectFill( bounds, borderColor ); GFX->getDrawUtil()->drawRectFill( fillBounds, fillColor ); }
void renderFilledBorder( const RectI &bounds, const ColorI &borderColor, const ColorI &fillColor ) { RectI fillBounds = bounds; fillBounds.inset( 1, 1 ); GFX->getDrawUtil()->drawRect( bounds, borderColor ); GFX->getDrawUtil()->drawRectFill( fillBounds, fillColor ); }
void GuiTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver) { if ( mList[cell.y].active ) { if (selected || (mProfile->mMouseOverSelected && mouseOver)) { RectI highlightRect = RectI(offset.x, offset.y, mCellSize.x, mCellSize.y); highlightRect.inset( 0, -1 ); renderFilledBorder( highlightRect, mProfile->mBorderColorHL, mProfile->mFillColorHL); GFX->getDrawUtil()->setBitmapModulation(mProfile->mFontColorHL); } else GFX->getDrawUtil()->setBitmapModulation(mouseOver ? mProfile->mFontColorHL : mProfile->mFontColor); } else GFX->getDrawUtil()->setBitmapModulation( mProfile->mFontColorNA ); const char *text = mList[cell.y].text; for(U32 index = 0; index < mColumnOffsets.size(); index++) { const char *nextCol = dStrchr(text, '\t'); if(mColumnOffsets[index] >= 0) { dsize_t slen; if(nextCol) slen = nextCol - text; else slen = dStrlen(text); Point2I pos(offset.x + 4 + mColumnOffsets[index], offset.y); RectI saveClipRect; bool clipped = false; if(mClipColumnText && (index != (mColumnOffsets.size() - 1))) { saveClipRect = GFX->getClipRect(); RectI clipRect(pos, Point2I(mColumnOffsets[index+1] - mColumnOffsets[index] - 4, mCellSize.y)); if(clipRect.intersect(saveClipRect)) { clipped = true; GFX->setClipRect( clipRect ); } } GFX->getDrawUtil()->drawTextN(mFont, pos, text, slen, mProfile->mFontColors); if(clipped) GFX->setClipRect( saveClipRect ); } if(!nextCol) break; text = nextCol+1; } }
UINT RenderCache::Paint(HDC hdc, RectI bounds, DisplayModel *dm, int pageNo, PageInfo *pageInfo, bool *renderOutOfDateCue) { assert(pageInfo->shown && 0.0 != pageInfo->visibleRatio); int rotation = dm->Rotation(); float zoom = dm->ZoomReal(); USHORT targetRes = GetTileRes(dm, pageNo); USHORT maxRes = GetMaxTileRes(dm, pageNo, rotation); if (maxRes < targetRes) maxRes = targetRes; Vec<TilePosition> queue; queue.Append(TilePosition(0, 0, 0)); UINT renderDelayMin = RENDER_DELAY_UNDEFINED; bool neededScaling = false; while (queue.Count() > 0) { TilePosition tile = queue.At(0); queue.RemoveAt(0); RectI tileOnScreen = GetTileOnScreen(dm->engine, pageNo, rotation, zoom, tile, pageInfo->pageOnScreen); tileOnScreen = pageInfo->pageOnScreen.Intersect(tileOnScreen); RectI isect = bounds.Intersect(tileOnScreen); if (isect.IsEmpty()) continue; bool isTargetRes = tile.res == targetRes; UINT renderDelay = PaintTile(hdc, isect, dm, pageNo, tile, tileOnScreen, isTargetRes, renderOutOfDateCue, isTargetRes ? &neededScaling : NULL); if (!(isTargetRes && 0 == renderDelay) && tile.res < maxRes) { queue.Append(TilePosition(tile.res + 1, tile.row * 2, tile.col * 2)); queue.Append(TilePosition(tile.res + 1, tile.row * 2, tile.col * 2 + 1)); queue.Append(TilePosition(tile.res + 1, tile.row * 2 + 1, tile.col * 2)); queue.Append(TilePosition(tile.res + 1, tile.row * 2 + 1, tile.col * 2 + 1)); } if (isTargetRes && renderDelay > 0) neededScaling = true; renderDelayMin = min(renderDelay, renderDelayMin); // paint tiles from left to right from top to bottom if (tile.res > 0 && queue.Count() > 0 && tile.res < queue.At(0).res) queue.Sort(cmpTilePosition); } #ifdef CONSERVE_MEMORY if (!neededScaling) { if (renderOutOfDateCue) *renderOutOfDateCue = false; // free tiles with different resolution TilePosition tile(targetRes, (USHORT)-1, 0); FreePage(dm, pageNo, &tile); } FreeNotVisible(); #endif return renderDelayMin; }
void Render(HDC hdc, RectI target, int pageNo, float zoom) { ScopedCritSec scope(&currAccess); if (currBmp && currPage == pageNo && currSize == target.Size()) currBmp->StretchDIBits(hdc, target); else if (!thread) { reqPage = pageNo; reqZoom = zoom; reqSize = target.Size(); thread = CreateThread(NULL, 0, RenderThread, this, 0, 0); } }
void fillOrAllocateTextureInternal(const RectI & bounds, Texture* texture, const RectI* roiParam, const unsigned char* originalRAMBuffer, int target, int texID, int format, int glType) { //GLuint savedTexture; //glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&savedTexture); { GLProtectAttrib<GL> a(GL_ENABLE_BIT); if (!texture->getBounds().contains(bounds)) { bool ok = texture->ensureTextureHasSize(bounds, originalRAMBuffer); assert(ok); } else { // The bounds of the texture might be different than the bounds of the buffer const RectI& texBounds = texture->getBounds(); int x1, y1, width, height; if (roiParam) { x1 = roiParam->x1 - texBounds.x1; y1 = roiParam->y1 - texBounds.y1; width = roiParam->width(); height = roiParam->height(); } else { x1 = bounds.x1 - texBounds.x1; y1 = bounds.y1 - texBounds.y1; width = bounds.width(); height = bounds.height(); } GL::Enable(target); GL::BindTexture (target, texID); GL::TexSubImage2D(target, 0, // level x1, y1, // xoffset, yoffset width, height, format, // format glType, // type originalRAMBuffer); GL::BindTexture (target, 0); glCheckError(GL); } } // GLProtectAttrib a(GL_ENABLE_BIT); }
static std::string makeUpFormatName(const RectI& format, double par) { // Format name was empty, too bad, make up one std::stringstream ss; ss << format.width(); ss << 'x'; ss << format.height(); if (par != 1.) { ss << ':'; ss << QString::number(par, 'f', 2).toStdString(); } return ss.str(); }
static BaseEngine *ps2pdf(const WCHAR *fileName) { // TODO: read from gswin32c's stdout instead of using a TEMP file ScopedMem<WCHAR> shortPath(path::ShortPath(fileName)); ScopedMem<WCHAR> tmpFile(path::GetTempPath(L"PsE")); ScopedFile tmpFileScope(tmpFile); ScopedMem<WCHAR> gswin32c(GetGhostscriptPath()); if (!shortPath || !tmpFile || !gswin32c) return NULL; // try to help Ghostscript determine the intended page size ScopedMem<WCHAR> psSetup; RectI page = ExtractDSCPageSize(fileName); if (!page.IsEmpty()) psSetup.Set(str::Format(L" << /PageSize [%i %i] >> setpagedevice", page.dx, page.dy)); ScopedMem<WCHAR> cmdLine(str::Format( L"\"%s\" -q -dSAFER -dNOPAUSE -dBATCH -dEPSCrop -sOutputFile=\"%s\" -sDEVICE=pdfwrite -c \".setpdfwrite%s\" -f \"%s\"", gswin32c, tmpFile, psSetup ? psSetup : L"", shortPath)); fprintf(stderr, "- %s:%d: using '%ls' for creating '%%TEMP%%\\%ls'\n", path::GetBaseName(__FILE__), __LINE__, gswin32c.Get(), path::GetBaseName(tmpFile)); // TODO: the PS-to-PDF conversion can hang the UI for several seconds HANDLE process = LaunchProcess(cmdLine, NULL, CREATE_NO_WINDOW); if (!process) return NULL; DWORD timeout = 10000; #ifdef DEBUG // allow to disable the timeout for debugging purposes if (GetEnvironmentVariable(L"SUMATRAPDF_NO_GHOSTSCRIPT_TIMEOUT", NULL, 0)) timeout = INFINITE; #endif DWORD exitCode = EXIT_FAILURE; WaitForSingleObject(process, timeout); GetExitCodeProcess(process, &exitCode); TerminateProcess(process, 1); CloseHandle(process); if (exitCode != EXIT_SUCCESS) return NULL; size_t len; ScopedMem<char> pdfData(file::ReadAll(tmpFile, &len)); if (!pdfData) return NULL; ScopedComPtr<IStream> stream(CreateStreamFromData(pdfData, len)); if (!stream) return NULL; return PdfEngine::CreateFromStream(stream); }
void ZoomToSelection(WindowInfo *win, float factor, bool scrollToFit, bool relative) { if (!win->IsDocLoaded()) return; PointI pt; bool zoomToPt = win->showSelection && win->selectionOnPage; // either scroll towards the center of the current selection if (zoomToPt) { RectI selRect; for (size_t i = 0; i < win->selectionOnPage->Count(); i++) { selRect = selRect.Union(win->selectionOnPage->At(i).GetRect(win->dm)); } ClientRect rc(win->hwndCanvas); pt.x = 2 * selRect.x + selRect.dx - rc.dx / 2; pt.y = 2 * selRect.y + selRect.dy - rc.dy / 2; pt.x = limitValue(pt.x, selRect.x, selRect.x + selRect.dx); pt.y = limitValue(pt.y, selRect.y, selRect.y + selRect.dy); int pageNo = win->dm->GetPageNoByPoint(pt); if (!win->dm->ValidPageNo(pageNo) || !win->dm->PageVisible(pageNo)) zoomToPt = false; } // or towards the top-left-most part of the first visible page else { int page = win->dm->FirstVisiblePageNo(); PageInfo *pageInfo = win->dm->GetPageInfo(page); if (pageInfo) { RectI visible = pageInfo->pageOnScreen.Intersect(win->canvasRc); pt = visible.TL(); int pageNo = win->dm->GetPageNoByPoint(pt); if (!visible.IsEmpty() && win->dm->ValidPageNo(pageNo) && win->dm->PageVisible(pageNo)) zoomToPt = true; } } if (!relative && (ZOOM_FIT_PAGE == factor || ZOOM_FIT_CONTENT == factor) && scrollToFit) zoomToPt = false; if (relative) win->dm->ZoomBy(factor, zoomToPt ? &pt : NULL); else win->dm->ZoomTo(factor, zoomToPt ? &pt : NULL); UpdateToolbarState(win); }
void PlaceToolInputState::MoveUnitPlacementSprite( const Vec2f& position ) { if( mUnitPlacementSprite ) { // Get the bounds of the animation. RectI bounds = mUnitPlacementSprite->GetClippingRectForCurrentAnimation(); // Calculate an offset to center the sprite. Vec2f offset( -1.0f * bounds.CenterX(), -1.0f * bounds.CenterY() ); // Move the Sprite to the position with an offset. mUnitPlacementSprite->Position = ( position + offset ); } }
static bool IsTileVisible(DisplayModel *dm, int pageNo, int rotation, float zoom, TilePosition tile, float fuzz=0) { if (!dm) return false; PageInfo *pageInfo = dm->GetPageInfo(pageNo); if (!dm->engine || !pageInfo) return false; RectI tileOnScreen = GetTileOnScreen(dm->engine, pageNo, rotation, zoom, tile, pageInfo->pageOnScreen); // consider nearby tiles visible depending on the fuzz factor tileOnScreen.x -= (int)(tileOnScreen.dx * fuzz * 0.5); tileOnScreen.dx = (int)(tileOnScreen.dx * (fuzz + 1)); tileOnScreen.y -= (int)(tileOnScreen.dy * fuzz * 0.5); tileOnScreen.dy = (int)(tileOnScreen.dy * (fuzz + 1)); RectI screen(PointI(), dm->viewPort.Size()); return !tileOnScreen.Intersect(screen).IsEmpty(); }
RenderedBitmap *DjVuEngineImpl::RenderBitmap(int pageNo, float zoom, int rotation, RectD *pageRect, RenderTarget target, AbortCookie **cookie_out) { ScopedCritSec scope(&gDjVuContext.lock); RectD pageRc = pageRect ? *pageRect : PageMediabox(pageNo); RectI screen = Transform(pageRc, pageNo, zoom, rotation).Round(); RectI full = Transform(PageMediabox(pageNo), pageNo, zoom, rotation).Round(); screen = full.Intersect(screen); ddjvu_page_t *page = ddjvu_page_create_by_pageno(doc, pageNo-1); if (!page) return NULL; int rotation4 = (((-rotation / 90) % 4) + 4) % 4; ddjvu_page_set_rotation(page, (ddjvu_page_rotation_t)rotation4); while (!ddjvu_page_decoding_done(page)) gDjVuContext.SpinMessageLoop(); if (ddjvu_page_decoding_error(page)) return NULL; bool isBitonal = DDJVU_PAGETYPE_BITONAL == ddjvu_page_get_type(page); ddjvu_format_t *fmt = ddjvu_format_create(isBitonal ? DDJVU_FORMAT_GREY8 : DDJVU_FORMAT_BGR24, 0, NULL); ddjvu_format_set_row_order(fmt, /* top_to_bottom */ TRUE); ddjvu_rect_t prect = { full.x, full.y, full.dx, full.dy }; ddjvu_rect_t rrect = { screen.x, 2 * full.y - screen.y + full.dy - screen.dy, screen.dx, screen.dy }; RenderedBitmap *bmp = NULL; int stride = ((screen.dx * (isBitonal ? 1 : 3) + 3) / 4) * 4; ScopedMem<char> bmpData(AllocArray<char>(stride * (screen.dy + 5))); if (bmpData) { #ifndef DEBUG ddjvu_render_mode_t mode = isBitonal ? DDJVU_RENDER_MASKONLY : DDJVU_RENDER_COLOR; #else // TODO: there seems to be a heap corruption in IW44Image.cpp // in debug builds when passing in DDJVU_RENDER_COLOR ddjvu_render_mode_t mode = DDJVU_RENDER_MASKONLY; #endif if (ddjvu_page_render(page, mode, &prect, &rrect, fmt, stride, bmpData.Get())) { bmp = new RenderedDjVuPixmap(bmpData, screen.Size(), isBitonal); AddUserAnnots(bmp, pageNo, zoom, rotation, screen); } } ddjvu_format_release(fmt); ddjvu_page_release(page); return bmp; }
// Show the result of a PDF forward-search synchronization (initiated by a DDE command) void ShowForwardSearchResult(WindowInfo *win, const WCHAR *fileName, UINT line, UINT col, UINT ret, UINT page, Vec<RectI> &rects) { win->fwdSearchMark.rects.Reset(); const PageInfo *pi = win->dm->GetPageInfo(page); if ((ret == PDFSYNCERR_SUCCESS) && (rects.Count() > 0) && (NULL != pi)) { // remember the position of the search result for drawing the rect later on win->fwdSearchMark.rects = rects; win->fwdSearchMark.page = page; win->fwdSearchMark.show = true; win->fwdSearchMark.hideStep = 0; if (!gUserPrefs->forwardSearch.highlightPermanent) SetTimer(win->hwndCanvas, HIDE_FWDSRCHMARK_TIMER_ID, HIDE_FWDSRCHMARK_DELAY_IN_MS, NULL); // Scroll to show the overall highlighted zone int pageNo = page; RectI overallrc = rects.At(0); for (size_t i = 1; i < rects.Count(); i++) overallrc = overallrc.Union(rects.At(i)); TextSel res = { 1, &pageNo, &overallrc }; if (!win->dm->PageVisible(page)) win->dm->GoToPage(page, 0, true); if (!win->dm->ShowResultRectToScreen(&res)) win->RepaintAsync(); if (IsIconic(win->hwndFrame)) ShowWindowAsync(win->hwndFrame, SW_RESTORE); return; } ScopedMem<WCHAR> buf; if (ret == PDFSYNCERR_SYNCFILE_NOTFOUND) ShowNotification(win, _TR("No synchronization file found")); else if (ret == PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED) ShowNotification(win, _TR("Synchronization file cannot be opened")); else if (ret == PDFSYNCERR_INVALID_PAGE_NUMBER) buf.Set(str::Format(_TR("Page number %u inexistant"), page)); else if (ret == PDFSYNCERR_NO_SYNC_AT_LOCATION) ShowNotification(win, _TR("No synchronization info at this position")); else if (ret == PDFSYNCERR_UNKNOWN_SOURCEFILE) buf.Set(str::Format(_TR("Unknown source file (%s)"), fileName)); else if (ret == PDFSYNCERR_NORECORD_IN_SOURCEFILE) buf.Set(str::Format(_TR("Source file %s has no synchronization point"), fileName)); else if (ret == PDFSYNCERR_NORECORD_FOR_THATLINE) buf.Set(str::Format(_TR("No result found around line %u in file %s"), line, fileName)); else if (ret == PDFSYNCERR_NOSYNCPOINT_FOR_LINERECORD) buf.Set(str::Format(_TR("No result found around line %u in file %s"), line, fileName)); if (buf) ShowNotification(win, buf); }
bool RectClipper::clipRect(const RectI& in_rRect, RectI& out_rRect) const { AssertFatal(in_rRect.isValidRect(), "Inappropriate min/max coords for rectangle"); if (in_rRect.point.x + in_rRect.extent.x - 1 < m_clipRect.point.x || in_rRect.point.x > m_clipRect.point.x + m_clipRect.extent.x - 1) return false; if (in_rRect.point.y + in_rRect.extent.y - 1 < m_clipRect.point.y || in_rRect.point.y > m_clipRect.point.y + m_clipRect.extent.y - 1) return false; if (in_rRect.point.x < m_clipRect.point.x) out_rRect.point.x = m_clipRect.point.x; else out_rRect.point.x = in_rRect.point.x; if (in_rRect.point.y < m_clipRect.point.y) out_rRect.point.y = m_clipRect.point.y; else out_rRect.point.y = in_rRect.point.y; Point2I bottomR; bottomR.x = getMin(in_rRect.point.x + in_rRect.extent.x - 1, m_clipRect.point.x + m_clipRect.extent.x - 1); bottomR.y = getMin(in_rRect.point.y + in_rRect.extent.y - 1, m_clipRect.point.y + m_clipRect.extent.y - 1); out_rRect.extent.x = bottomR.x - out_rRect.point.x + 1; out_rRect.extent.x = bottomR.y - out_rRect.point.y + 1; return true; }
// The extent of the current project in canonical coordinates. // The extent is the size of the 'output' for the current project. See ProjectCoordinateSystems // for more infomation on the project extent. The extent is in canonical coordinates and only // returns the top right position, as the extent is always rooted at 0,0. For example a PAL SD // project would have an extent of 768, 576. void OfxImageEffectInstance::getProjectExtent(double & xSize, double & ySize) const { Format f; _ofxEffectInstance->getRenderFormat(&f); RectI pixelF; pixelF.x1 = f.x1; pixelF.x2 = f.x2; pixelF.y1 = f.y1; pixelF.y2 = f.y2; RectD canonicalF; pixelF.toCanonical_noClipping(0, f.getPixelAspectRatio(), &canonicalF); xSize = canonicalF.right(); ySize = canonicalF.top(); }
// The offset of the current project in canonical coordinates. // The offset is related to the kOfxImageEffectPropProjectSize and is the offset from the origin // of the project 'subwindow'. For example for a PAL SD project that is in letterbox form, the // project offset is the offset to the bottom left hand corner of the letter box. The project // offset is in canonical coordinates. void OfxImageEffectInstance::getProjectOffset(double & xOffset, double & yOffset) const { Format f; _ofxEffectInstance->getRenderFormat(&f); RectI pixelF; pixelF.x1 = f.x1; pixelF.x2 = f.x2; pixelF.y1 = f.y1; pixelF.y2 = f.y2; RectD canonicalF; pixelF.toCanonical_noClipping(0, f.getPixelAspectRatio(), &canonicalF); xOffset = canonicalF.left(); yOffset = canonicalF.bottom(); }
static void DrawFrame2(Graphics &g, RectI r) { g.SetCompositingQuality(CompositingQualityHighQuality); g.SetSmoothingMode(SmoothingModeAntiAlias); g.SetPageUnit(UnitPixel); Font f(L"Impact", 40, FontStyleRegular); CalcLettersLayout(g, &f, r.dx); SolidBrush bgBrush(Color(0xff, 0xf2, 0)); Rect r2(r.ToGdipRect()); r2.Inflate(1, 1); g.FillRectangle(&bgBrush, r2); Font f2(L"Impact", 16, FontStyleRegular); DrawSumatraLetters(g, &f, &f2, 18.f); if (gShowOptions) return; REAL msgY = (REAL)(r.dy / 2); if (gMsg) msgY += DrawMessage(g, gMsg, msgY, (REAL)r.dx, gMsgColor) + 5; if (gMsgError) DrawMessage(g, gMsgError, msgY, (REAL)r.dx, COLOR_MSG_FAILED); }
void GuiBitmapCtrl::onRender(Point2I offset, const RectI &updateRect) { GFXDEBUGEVENT_SCOPE_EX( GuiBitmapCtrl_onRender, ColorI::GREEN, avar("GuiBitmapCtrl: %s", mBitmapName.c_str()) ); if (mTextureObject) { GFX->getDrawUtil()->clearBitmapModulation(); if(mWrap) { // We manually draw each repeat because non power of two textures will // not tile correctly when rendered with GFX->drawBitmapTile(). The non POT // bitmap will be padded by the hardware, and we'll see lots of slack // in the texture. So... lets do what we must: draw each repeat by itself: GFXTextureObject* texture = mTextureObject; RectI srcRegion; RectI dstRegion; float xdone = ((float)getExtent().x/(float)texture->mBitmapSize.x)+1; float ydone = ((float)getExtent().y/(float)texture->mBitmapSize.y)+1; int xshift = mStartPoint.x%texture->mBitmapSize.x; int yshift = mStartPoint.y%texture->mBitmapSize.y; for(int y = 0; y < ydone; ++y) for(int x = 0; x < xdone; ++x) { srcRegion.set(0,0,texture->mBitmapSize.x,texture->mBitmapSize.y); dstRegion.set( ((texture->mBitmapSize.x*x)+offset.x)-xshift, ((texture->mBitmapSize.y*y)+offset.y)-yshift, texture->mBitmapSize.x, texture->mBitmapSize.y); GFX->getDrawUtil()->drawBitmapStretchSR(texture,dstRegion, srcRegion, GFXBitmapFlip_None, GFXTextureFilterLinear); } } else { RectI rect(offset, getExtent()); GFX->getDrawUtil()->drawBitmapStretch(mTextureObject, rect, GFXBitmapFlip_None, GFXTextureFilterLinear, false); } } if (mProfile->mBorder || !mTextureObject) { RectI rect(offset.x, offset.y, getExtent().x, getExtent().y); GFX->getDrawUtil()->drawRect(rect, mProfile->mBorderColor); } renderChildControls(offset, updateRect); }
void OnMenuAbout() { if (gHwndAbout) { SetActiveWindow(gHwndAbout); return; } if (!gAtomAbout) { WNDCLASSEX wcex; FillWndClassEx(wcex, ghinst, ABOUT_CLASS_NAME, WndProcAbout); wcex.hIcon = LoadIcon(ghinst, MAKEINTRESOURCE(IDI_SUMATRAPDF)); gAtomAbout = RegisterClassEx(&wcex); CrashIf(!gAtomAbout); } gHwndAbout = CreateWindow( ABOUT_CLASS_NAME, ABOUT_WIN_TITLE, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, ghinst, NULL); if (!gHwndAbout) return; ToggleWindowStyle(gHwndAbout, WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT, IsUIRightToLeft(), GWL_EXSTYLE); // get the dimensions required for the about box's content RectI rc; PAINTSTRUCT ps; HDC hdc = BeginPaint(gHwndAbout, &ps); SetLayout(hdc, LAYOUT_LTR); UpdateAboutLayoutInfo(gHwndAbout, hdc, &rc); EndPaint(gHwndAbout, &ps); rc.Inflate(ABOUT_RECT_PADDING, ABOUT_RECT_PADDING); // resize the new window to just match these dimensions WindowRect wRc(gHwndAbout); ClientRect cRc(gHwndAbout); wRc.dx += rc.dx - cRc.dx; wRc.dy += rc.dy - cRc.dy; MoveWindow(gHwndAbout, wRc.x, wRc.y, wRc.dx, wRc.dy, FALSE); ShowWindow(gHwndAbout, SW_SHOW); }