int wxGridCellAutoWrapStringRenderer::GetBestWidth(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, int row, int col, int height) { const int lineHeight = dc.GetCharHeight(); // Maximal number of lines that fully fit but at least 1. const size_t maxLines = height - AUTOWRAP_Y_MARGIN < lineHeight ? 1 : (height - AUTOWRAP_Y_MARGIN)/lineHeight; // Increase width until all the text fits. // // TODO: this is not the most efficient to do it for the long strings. const int charWidth = dc.GetCharWidth(); int width = 2*charWidth; while ( GetTextLines(grid, dc, attr, wxSize(width, height), row, col).size() > maxLines ) width += charWidth; return width; }
/* static */ wxString wxControlBase::Ellipsize(const wxString& label, const wxDC& dc, wxEllipsizeMode mode, int maxFinalWidth, int flags) { wxString ret; // these cannot be cached between different Ellipsize() calls as they can // change because of e.g. a font change; however we calculate them only once // when ellipsizing multiline labels: int replacementWidth = dc.GetTextExtent(wxELLIPSE_REPLACEMENT).GetWidth(); int marginWidth = dc.GetCharWidth(); // NB: we must handle correctly labels with newlines: wxString curLine; for ( wxString::const_iterator pc = label.begin(); ; ++pc ) { if ( pc == label.end() || *pc == wxS('\n') ) { curLine = DoEllipsizeSingleLine(curLine, dc, mode, maxFinalWidth, replacementWidth, marginWidth); // add this (ellipsized) row to the rest of the label ret << curLine; if ( pc == label.end() ) { // NOTE: this is the return which always exits the function return ret; } else { ret << *pc; curLine.clear(); } } // we need to remove mnemonics from the label for correct calculations else if ( *pc == wxS('&') && (flags & wxELLIPSIZE_PROCESS_MNEMONICS) != 0 ) { // pc+1 is safe: at worst we'll be at end() wxString::const_iterator next = pc + 1; if ( next != label.end() && *next == wxS('&') ) curLine += wxS('&'); // && becomes & //else: remove this ampersand } // we need also to expand tabs to properly calc their size else if ( *pc == wxS('\t') && (flags & wxELLIPSIZE_EXPAND_TAB) != 0 ) { // Windows natively expands the TABs to 6 spaces. Do the same: curLine += wxS(" "); } else { curLine += *pc; } } // this return would generate a // warning C4702: unreachable code // with MSVC since the function always exits from inside the loop //return ret; }
/* * Here we do the actual rendering. I put it in a separate * method so that it can work no matter what type of DC * (e.g. wxPaintDC or wxClientDC) is used. */ void BasicDrawPane::Render(wxDC& dc) { int width, height; this->GetSize(&width, &height); if ( m_bgColor.IsOk() ) { dc.SetBrush(wxBrush(m_bgColor)); dc.DrawRectangle(0, 0, width, height); } if ( m_textForeGround.IsOk() ) { dc.SetTextForeground( m_textForeGround ); } if ( !m_text.IsEmpty() ) { dc.SetBackgroundMode(wxTRANSPARENT); dc.SetFont( m_font ); /* * ちょうど中央表示できるよう調整 */ const int cHeight = dc.GetCharHeight(); const int cWidth = dc.GetCharWidth(); const int textLen = m_text.Len(); const int textHalfSize = textLen * cWidth / 2; dc.DrawText( m_text, width / 2 - textHalfSize, height / 2 - cHeight / 2 ); } }
static void AdjustFontSize(wxFont& font, wxDC& dc, const wxSize& pixelSize) { int currentSize = 0; int largestGood = 0; int smallestBad = 0; bool initialGoodFound = false; bool initialBadFound = false; // NB: this assignment was separated from the variable definition // in order to fix a gcc v3.3.3 compiler crash currentSize = font.GetPointSize(); while (currentSize > 0) { dc.SetFont(font); // if currentSize (in points) results in a font that is smaller // than required by pixelSize it is considered a good size if (dc.GetCharHeight() <= pixelSize.GetHeight() && (!pixelSize.GetWidth() || dc.GetCharWidth() <= pixelSize.GetWidth())) { largestGood = currentSize; initialGoodFound = true; } else { smallestBad = currentSize; initialBadFound = true; } if (!initialGoodFound) { currentSize /= 2; } else if (!initialBadFound) { currentSize *= 2; } else { int distance = smallestBad - largestGood; if (distance == 1) break; currentSize = largestGood + distance / 2; } font.SetPointSize(currentSize); } if (currentSize != largestGood) font.SetPointSize(largestGood); }
void StateEvaluationTreePanel::render(wxDC &dc) { if (Settings.m_ColourScheme == nullptr) return; PrepareDC(dc); auto const &Scheme = *(Settings.m_ColourScheme); dc.SetBackground(wxBrush{Scheme.getDefault().GetBackground()}); dc.Clear(); if (Statement.empty()) return; auto const ActiveStmt = ActiveFn->getActiveStmt(); if (!ActiveStmt) return; dc.SetFont(CodeFont); // Draw the sub-Stmts' nodes. for (auto const &Node : Nodes) { // Don't draw hovered nodes, they will be drawn later. if (&*HoverNodeIt == &Node || &*ReplayHoverNodeIt == &Node) continue; auto const DoHighlight = (HighlightedStmt && Node.Statement == HighlightedStmt) || (HighlightedValue && Node.Value.get() == HighlightedValue); if (DoHighlight) drawNode(dc, Scheme, Node, NodeDecoration::Highlighted); else if (Node.Statement == ActiveStmt) drawNode(dc, Scheme, Node, NodeDecoration::Active); else drawNode(dc, Scheme, Node, NodeDecoration::None); } // Redraw the hovered nodes, so that they outrank active node highlighting. if (HoverNodeIt != Nodes.end()) drawNode(dc, Scheme, *HoverNodeIt, NodeDecoration::Highlighted); if (ReplayHoverNodeIt != Nodes.end()) drawNode(dc, Scheme, *ReplayHoverNodeIt, NodeDecoration::Highlighted); // Draw the pretty-printed Stmt's string. dc.SetTextForeground(Scheme.getDefault().GetForeground()); wxCoord const PageBorderH = dc.GetCharWidth() * Settings.PageBorderHorizontal; wxCoord const PageBorderV = dc.GetCharHeight() * Settings.PageBorderVertical; dc.DrawText(Statement, PageBorderH, PageBorderV); }
void ChipPackage::DrawPins(wxDC& dc, const wxPoint& pt, unsigned int PackageLen, unsigned int FirstPin, unsigned int LastPin, int flags, wxDirection dir) { wxASSERT_MSG(LastPin>FirstPin, "invalid pin indexes"); // NOTE: inside this function context // pin number == the index of the pin (e.g. "1", "2", etc) // pin name == pin label == the name of the pin signal (e.g. "VCC", "GND" etc) // pin == pin rectangle // some drawing constants: const unsigned int PinCount = LastPin - FirstPin; // pin height is calculated imposing that // 1) PinCount*PinH + (PinCount+1)*PinSpacing = PackageLen // 2) PinSpacing = PinH/2 // solving for PinH yields: unsigned int PinH = (unsigned int)floor(2*PackageLen/(3.0*PinCount+1)); unsigned int PinW = (unsigned int)1.5*PinH; const unsigned int PinSpacing = (const unsigned int)floor(PinH/2.0); // the error which force us to have a "pin y offset" is caused by rounding // in the calculation of PinH: const int PinOffset = (PackageLen - (PinCount*PinH + (PinCount+1)*PinSpacing))/2; wxASSERT(PinOffset>=0); if (int(PinH*0.8) == 0) return; // this happens for very small package sizes; // the check avoids an assertion failure from wxFont ctor // select a font suitable for the PinH we have computed above: int fSize = int(PinH*0.8); if(fSize>12)fSize=12; wxFont fnt(wxSize(0,fSize), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD); dc.SetFont(fnt); const unsigned int PinNumberW = 2*dc.GetCharWidth(); const unsigned int PinNumberH = dc.GetCharHeight(); bool invertOrder = (flags & DRAWPIN_INVERTED_ORDER) != 0; unsigned int start = invertOrder ? LastPin-1 : FirstPin; unsigned int end = invertOrder ? FirstPin-1 : LastPin; int inc = invertOrder ? -1 : +1; if (dir == wxLEFT || dir == wxRIGHT) { unsigned int PinX = (dir == wxLEFT) ? pt.x-PinW+1 : pt.x-1; unsigned int PinY = pt.y + PinOffset + PinSpacing; unsigned int PinNumberX = (dir == wxLEFT) ? pt.x+PinSpacing : pt.x-PinNumberW-PinSpacing; if (flags & DRAWPIN_NUMBERS_INSIDE_PINS) PinNumberX = PinX + (PinW-PinNumberW)/2; // draw the pins organizing them in a vertical column for (unsigned int i=start; i != end; i+=inc) { unsigned int PinNumberY = PinY + (PinH-PinNumberH)/2; unsigned int pinLabelX = (dir == wxLEFT) ? PinX-PinSpacing-dc.GetTextExtent(PinNames[i]).GetWidth() : PinX+PinW+PinSpacing; unsigned int pinLabelY = PinNumberY; // draw the pin rect dc.DrawRectangle(PinX, PinY, PinW, PinH); // print the pin number dc.SetTextForeground(IsICSPPin(i) ? *wxRED : *wxBLACK); dc.DrawText(wxString::Format(("%d"), i+1), PinNumberX, PinNumberY); // print the pin name dc.DrawText(PinNames[i], pinLabelX, pinLabelY); PinY += PinH+PinSpacing; } } else if (dir == wxTOP || dir == wxBOTTOM) { SWAP(PinH, PinW, unsigned int); // in this case the PackageLen is the number of horizontal pixels available // for drawing the pin strip; thus we want to compute PinW and set PinH // VERY IMPORTANT: the code below is the dual of the code for wxLEFT|wxRIGHT case! // If you change something here, you may want to change it also // above, with the appropriate differences // NOTE: remember however that the text is drawn rotated by 90 degrees unsigned int PinX = pt.x + PinOffset + PinSpacing; unsigned int PinY = (dir == wxTOP) ? pt.y-PinH+1 : pt.y-1; unsigned int PinNumberY = (dir == wxTOP) ? pt.y+PinSpacing : pt.y-PinNumberH-PinSpacing; if (flags & DRAWPIN_NUMBERS_INSIDE_PINS) PinNumberY = PinY + (PinH-PinNumberW)/2; // draw the pins organizing them in a horizontal column for (unsigned int i=start; i != end; i+=inc) { unsigned int PinNumberX = PinX + PinNumberH + (PinW-PinNumberH)/2; unsigned int pinLabelX = PinNumberX; unsigned int pinLabelY = (dir == wxTOP) ? PinY-PinSpacing-dc.GetTextExtent(PinNames[i]).GetWidth() : PinY+PinH+PinSpacing; // draw the pin rect dc.DrawRectangle(PinX, PinY, PinW, PinH); // print the pin number dc.SetTextForeground(IsICSPPin(i) ? *wxRED : *wxBLACK); dc.DrawRotatedText(wxString::Format(("%d"), i+1), PinNumberX, PinNumberY, -90); // print the pin name dc.DrawRotatedText(PinNames[i], pinLabelX, pinLabelY, -90); PinX += PinW+PinSpacing; } } else wxLogWarning(_("Invalid direction")); }
int SurfaceImpl::AverageCharWidth(Font &font) { SetFont(font); return hdc->GetCharWidth(); }
void StateEvaluationTreePanel::drawNode(wxDC &DC, ColourScheme const &Scheme, NodeInfo const &Node, NodeDecoration const Decoration) { auto const CharWidth = DC.GetCharWidth(); auto const CharHeight = DC.GetCharHeight(); wxCoord const PageBorderV = CharHeight * Settings.PageBorderVertical; // Determine the indicator (if any). IndicatorStyle const *Indicator = nullptr; switch (Decoration) { case NodeDecoration::None: break; case NodeDecoration::Active: Indicator = &(Scheme.getActiveCode()); break; case NodeDecoration::Highlighted: Indicator = &(Scheme.getHighlightCode()); break; } // Set the background colour. DC.SetPen(wxPen{Scheme.getDefault().GetForeground(), Settings.PenWidth}); DC.SetBrush(wxBrush{Scheme.getDefault().GetBackground()}); DC.SetTextForeground(Scheme.getDefault().GetForeground()); // Also highlight this node's area in the pretty-printed Stmt. if (Indicator) { drawIndicatorAtArea(DC, *Indicator, Node.XStart, PageBorderV, Node.XEnd - Node.XStart, CharHeight); } // Draw the background. wxPen const PrevPen = DC.GetPen(); DC.SetPen(wxPen{DC.GetBrush().GetColour()}); DC.DrawRectangle(Node.XStart, Node.YStart, Node.XEnd - Node.XStart, Node.YEnd - Node.YStart); DC.SetPen(PrevPen); // Draw the line over the node. DC.DrawLine(Node.XStart, Node.YStart, Node.XEnd + 1, Node.YStart); // Draw the base indicator on the node (if any). if (Indicator) { drawIndicatorAtArea(DC, *Indicator, Node.XStart, Node.YStart, Node.XEnd - Node.XStart, Node.YEnd - Node.YStart); } // Draw the error indicator if the node has an error. if (Node.Error == NodeError::Error) { drawIndicatorAtArea(DC, Scheme.getErrorCode(), Node.XStart, Node.YStart, Node.XEnd - Node.XStart, Node.YEnd - Node.YStart); } // Draw the node's value string. if (Node.Value) { auto const ValText = Node.ValueStringShort; auto const TextWidth = CharWidth * ValText.size(); auto const NodeWidth = CharWidth * Node.RangeLength; auto const Offset = (NodeWidth - TextWidth) / 2; DC.DrawText(ValText, Node.XStart + Offset, Node.YStart); } }
// draw the continuity starting at a specific offset void DrawCont(wxDC& dc, const CC_textline_list& print_continuity, const wxRect& bounding, bool landscape) { SaveAndRestore_DeviceOrigin orig_dev(dc); SaveAndRestore_UserScale orig_scale(dc); SaveAndRestore_TextForeground orig_text(dc); SaveAndRestore_Font orig_font(dc); #if DEBUG dc.DrawRectangle(bounding); #endif dc.SetTextForeground(*wxBLACK); int pageMiddle = (bounding.GetWidth()/2); size_t numLines = 0; for (auto text = print_continuity.begin(); text != print_continuity.end(); ++text) { if (text->GetOnSheet()) { ++numLines; } } int font_size = ((bounding.GetBottom() - bounding.GetTop()) - (numLines - 1)*2)/(numLines ? numLines : 1); //font size, we scale to be no more than 256 pixels. font_size = std::min(font_size, 10); wxFont *contPlainFont = wxTheFontList->FindOrCreateFont(font_size, wxMODERN, wxNORMAL, wxNORMAL); wxFont *contBoldFont = wxTheFontList->FindOrCreateFont(font_size, wxMODERN, wxNORMAL, wxBOLD); wxFont *contItalFont = wxTheFontList->FindOrCreateFont(font_size, wxMODERN, wxITALIC, wxNORMAL); wxFont *contBoldItalFont = wxTheFontList->FindOrCreateFont(font_size, wxMODERN, wxITALIC, wxBOLD); dc.SetFont(*contPlainFont); const wxCoord maxtexth = contPlainFont->GetPointSize()+2; float y = bounding.GetTop(); const wxCoord charWidth = dc.GetCharWidth(); for (auto& cont : print_continuity) { float x = bounding.GetLeft(); // Determine how to center the text if (cont.GetCenter()) { x += pageMiddle; auto chunks = cont.GetChunks(); for (auto& c : chunks) { bool do_tab = false; switch (c.font) { case PSFONT_SYMBOL: { wxCoord textw, texth; dc.GetTextExtent(wxT("O"), &textw, &texth); x += textw * c.text.length(); } break; case PSFONT_NORM: dc.SetFont(*contPlainFont); break; case PSFONT_BOLD: dc.SetFont(*contBoldFont); break; case PSFONT_ITAL: dc.SetFont(*contItalFont); break; case PSFONT_BOLDITAL: dc.SetFont(*contBoldItalFont); break; case PSFONT_TAB: do_tab = true; break; } if (!do_tab && (c.font != PSFONT_SYMBOL)) { wxCoord textw, texth; dc.GetTextExtent(c.text, &textw, &texth); x -= textw/2; } } } // now draw the text unsigned tabnum = 0; auto chunks = cont.GetChunks(); for (auto& c : chunks) { bool do_tab = false; switch (c.font) { case PSFONT_NORM: case PSFONT_SYMBOL: dc.SetFont(*contPlainFont); break; case PSFONT_BOLD: dc.SetFont(*contBoldFont); break; case PSFONT_ITAL: dc.SetFont(*contItalFont); break; case PSFONT_BOLDITAL: dc.SetFont(*contBoldItalFont); break; case PSFONT_TAB: { tabnum++; wxCoord textw = bounding.GetLeft() + charWidth * TabStops(tabnum, landscape); if (textw >= x) x = textw; else x += charWidth; do_tab = true; } break; default: break; } if (c.font == PSFONT_SYMBOL) { wxCoord textw, texth, textd; dc.GetTextExtent(wxT("O"), &textw, &texth, &textd); const float d = textw; const float top_y = y + texth - textd - textw; for (std::string::const_iterator s = c.text.begin(); s != c.text.end(); s++) { { dc.SetPen(*wxBLACK_PEN); SYMBOL_TYPE sym = (SYMBOL_TYPE)(*s - 'A'); switch (sym) { case SYMBOL_SOL: case SYMBOL_SOLBKSL: case SYMBOL_SOLSL: case SYMBOL_SOLX: dc.SetBrush(*wxBLACK_BRUSH); break; default: dc.SetBrush(*wxTRANSPARENT_BRUSH); } dc.DrawEllipse(x, top_y, d, d); switch (sym) { case SYMBOL_SL: case SYMBOL_X: case SYMBOL_SOLSL: case SYMBOL_SOLX: dc.DrawLine(x-1, top_y + d+1, x + d+1, top_y-1); break; default: break; } switch (sym) { case SYMBOL_BKSL: case SYMBOL_X: case SYMBOL_SOLBKSL: case SYMBOL_SOLX: dc.DrawLine(x-1, top_y-1, x + d+1, top_y + d+1); break; default: break; } } x += d; } } else { if (!do_tab) { wxCoord textw, texth; dc.GetTextExtent(c.text, &textw, &texth); dc.DrawText(c.text, x, y); x += textw; } } } y += maxtexth; } #if DEBUG char buffer[100]; snprintf(buffer, sizeof(buffer), "TopLeft %d, %d", bounding.GetTopLeft().x, bounding.GetTopLeft().y); dc.DrawText(buffer, bounding.GetTopLeft()); snprintf(buffer, sizeof(buffer), "BottomRight %d, %d", bounding.GetBottomRight().x, bounding.GetBottomRight().y); dc.DrawText(buffer, bounding.GetBottomRight()); #endif }