Exemple #1
0
const EDA_RECT SCH_SHEET::GetBoundingBox() const
{
    wxPoint end;
    EDA_RECT box( m_pos, m_size );
    int      lineWidth = GetPenSize();

    // Determine length of texts
    wxString text    = wxT( "Sheet: " ) + m_name;
    int      textlen  = GraphicTextWidth( text, wxSize( m_sheetNameSize, m_sheetNameSize ),
                                          false, false );

    text = wxT( "File: " ) + m_fileName;
    int      textlen2 = GraphicTextWidth( text, wxSize( m_fileNameSize, m_fileNameSize ),
                                          false, false );

    // Calculate bounding box X size:
    textlen = std::max( textlen, textlen2 );
    end.x = std::max( m_size.x, textlen );

    // Calculate bounding box pos:
    end.y = m_size.y;
    end += m_pos;

    // Move upper and lower limits to include texts:
    box.SetY( box.GetY() - ( KiROUND( m_sheetNameSize * 1.3 ) + 8 ) );
    end.y += KiROUND( m_fileNameSize * 1.3 ) + 8;

    box.SetEnd( end );
    box.Inflate( lineWidth / 2 );

    return box;
}
int EDA_TEXT::LenSize( const wxString& aLine ) const
{
    return GraphicTextWidth( aLine, m_Size.x, m_Italic, m_Bold );
}
/**
 * Function DrawGraphicText
 * Draw a graphic text (like module texts)
 *  @param aClipBox = the clipping rect, or NULL if no clipping
 *  @param aDC = the current Device Context. NULL if draw within a 3D GL Canvas
 *  @param aPos = text position (according to h_justify, v_justify)
 *  @param aColor (enum EDA_COLOR_T) = text color
 *  @param aText = text to draw
 *  @param aOrient = angle in 0.1 degree
 *  @param aSize = text size (size.x or size.y can be < 0 for mirrored texts)
 *  @param aH_justify = horizontal justification (Left, center, right)
 *  @param aV_justify = vertical justification (bottom, center, top)
 *  @param aWidth = line width (pen width) (use default width if aWidth = 0)
 *      if width < 0 : draw segments in sketch mode, width = abs(width)
 *      Use a value min(aSize.x, aSize.y) / 5 for a bold text
 *  @param aItalic = true to simulate an italic font
 *  @param aBold = true to use a bold font. Useful only with default width value (aWidth = 0)
 *  @param aCallback() = function called (if non null) to draw each segment.
 *                  used to draw 3D texts or for plotting, NULL for normal drawings
 *  @param aPlotter = a pointer to a PLOTTER instance, when this function is used to plot
 *                  the text. NULL to draw this text.
 */
void DrawGraphicText( EDA_RECT* aClipBox,
                      wxDC* aDC,
                      const wxPoint& aPos,
                      EDA_COLOR_T aColor,
                      const wxString& aText,
                      double aOrient,
                      const wxSize& aSize,
                      enum EDA_TEXT_HJUSTIFY_T aH_justify,
                      enum EDA_TEXT_VJUSTIFY_T aV_justify,
                      int aWidth,
                      bool aItalic,
                      bool aBold,
                      void (* aCallback)( int x0, int y0, int xf, int yf ),
                      PLOTTER* aPlotter )
{
    int         AsciiCode;
    int         x0, y0;
    int         size_h, size_v;
    unsigned    ptr;
    int         dx, dy;                     // Draw coordinate for segments to draw. also used in some other calculation
    wxPoint     current_char_pos;           // Draw coordinates for the current char
    wxPoint     overbar_pos;                // Start point for the current overbar
    int         overbar_italic_comp;        // Italic compensation for overbar
    #define        BUF_SIZE 100
    wxPoint coord[BUF_SIZE + 1];                // Buffer coordinate used to draw polylines (one char shape)
    bool    sketch_mode     = false;
    bool    italic_reverse  = false;            // true for mirrored texts with m_Size.x < 0

    size_h  = aSize.x;                          /* PLEASE NOTE: H is for HORIZONTAL not for HEIGHT */
    size_v  = aSize.y;

    if( aWidth == 0 && aBold ) // Use default values if aWidth == 0
        aWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );

    if( aWidth < 0 )
    {
        aWidth = -aWidth;
        sketch_mode = true;
    }

#ifdef CLIP_PEN      // made by draw and plot functions
    aWidth = Clamp_Text_PenSize( aWidth, aSize, aBold );
#endif

    if( size_h < 0 ) // text is mirrored using size.x < 0 (mirror / Y axis)
        italic_reverse = true;

    unsigned char_count = NegableTextLength( aText );

    if( char_count == 0 )
        return;

    current_char_pos = aPos;

    dx  = GraphicTextWidth( aText, size_h, aItalic, aWidth );
    dy  = size_v;

    /* Do not draw the text if out of draw area! */
    if( aClipBox )
    {
        int xm, ym, ll, xc, yc;
        ll = std::abs( dx );

        xc  = current_char_pos.x;
        yc  = current_char_pos.y;

        x0  = aClipBox->GetX() - ll;
        y0  = aClipBox->GetY() - ll;
        xm  = aClipBox->GetRight() + ll;
        ym  = aClipBox->GetBottom() + ll;

        if( xc < x0 )
            return;

        if( yc < y0 )
            return;

        if( xc > xm )
            return;

        if( yc > ym )
            return;
    }


    /* Compute the position of the first letter of the text
     * this position is the position of the left bottom point of the letter
     * this is the same as the text position only for a left and bottom justified text
     * In others cases, this position must be calculated from the text position ans size
     */

    switch( aH_justify )
    {
    case GR_TEXT_HJUSTIFY_CENTER:
        current_char_pos.x -= dx / 2;
        break;

    case GR_TEXT_HJUSTIFY_RIGHT:
        current_char_pos.x -= dx;
        break;

    case GR_TEXT_HJUSTIFY_LEFT:
        break;
    }

    switch( aV_justify )
    {
    case GR_TEXT_VJUSTIFY_CENTER:
        current_char_pos.y += dy / 2;
        break;

    case GR_TEXT_VJUSTIFY_TOP:
        current_char_pos.y += dy;
        break;

    case GR_TEXT_VJUSTIFY_BOTTOM:
        break;
    }

    // Note: if aPanel == NULL, we are using a GL Canvas that handle scaling
    if( aSize.x == 0 )
        return;

    /* if a text size is too small, the text cannot be drawn, and it is drawn as a single
     * graphic line */
    if( aDC && ( aDC->LogicalToDeviceYRel( std::abs( aSize.y ) ) < MIN_DRAWABLE_TEXT_SIZE ))
    {
        // draw the text as a line always vertically centered
        wxPoint end( current_char_pos.x + dx, current_char_pos.y );

        RotatePoint( &current_char_pos, aPos, aOrient );
        RotatePoint( &end, aPos, aOrient );

        if( aPlotter )
        {
            aPlotter->MoveTo( current_char_pos );
            aPlotter->FinishTo( end );
        }
        else if( aCallback )
        {
            aCallback( current_char_pos.x, current_char_pos.y, end.x, end.y );
        }
        else
            GRLine( aClipBox, aDC,
                    current_char_pos.x, current_char_pos.y, end.x, end.y, aWidth, aColor );

        return;
    }

    if( aItalic )
    {
        overbar_italic_comp = OverbarPositionY( size_v ) / 8;

        if( italic_reverse )
        {
            overbar_italic_comp = -overbar_italic_comp;
        }
    }
    else
    {
        overbar_italic_comp = 0;
    }

    int overbars = 0;   // Number of '~' seen (except '~~')
    ptr = 0;            // ptr = text index

    while( ptr < char_count )
    {
        if( aText[ptr + overbars] == '~' )
        {
            if( ptr + overbars + 1 < aText.length()
                && aText[ptr + overbars + 1] == '~' )   /* '~~' draw as '~' */
                ptr++;                                  // skip first '~' char and draw second

            else
            {
                // Found an overbar, adjust the pointers
                overbars++;

                if( overbars & 1 )      // odd overbars count
                {
                    // Starting the overbar
                    overbar_pos     = current_char_pos;
                    overbar_pos.x   += overbar_italic_comp;
                    overbar_pos.y   -= OverbarPositionY( size_v );
                    RotatePoint( &overbar_pos, aPos, aOrient );
                }
                else
                {
                    // Ending the overbar
                    coord[0]        = overbar_pos;
                    overbar_pos     = current_char_pos;
                    overbar_pos.x   += overbar_italic_comp;
                    overbar_pos.y   -= OverbarPositionY( size_v );
                    RotatePoint( &overbar_pos, aPos, aOrient );
                    coord[1] = overbar_pos;
                    // Plot the overbar segment
                    DrawGraphicTextPline( aClipBox, aDC, aColor, aWidth,
                                          sketch_mode, 2, coord, aCallback, aPlotter );
                }

                continue;    // Skip ~ processing
            }
        }

        AsciiCode = aText.GetChar( ptr + overbars );

        const char* ptcar = GetHersheyShapeDescription( AsciiCode );
        // Get metrics
        int         xsta    = *ptcar++ - 'R';
        int         xsto    = *ptcar++ - 'R';
        int         point_count = 0;
        bool        endcar = false;

        while( !endcar )
        {
            int hc1, hc2;
            hc1 = *ptcar++;

            if( hc1 )
            {
                hc2 = *ptcar++;
            }
            else
            {
                // End of character, insert a synthetic pen up:
                hc1    = ' ';
                hc2    = 'R';
                endcar = true;
            }

            // Do the Hershey decode thing:
            // coordinates values are coded as <value> + 'R'
            hc1 -= 'R';
            hc2 -= 'R';

            // Pen up request
            if( hc1 == -50 && hc2 == 0 )
            {
                if( point_count )
                {
                    if( aWidth <= 1 )
                        aWidth = 0;

                    DrawGraphicTextPline( aClipBox, aDC, aColor, aWidth,
                                          sketch_mode, point_count, coord,
                                          aCallback, aPlotter );
                }

                point_count = 0;
            }
            else
            {
                wxPoint currpoint;
                hc1 -= xsta; hc2 -= 10;    // Align the midpoint
                hc1  = KiROUND( hc1 * size_h * s_HersheyScaleFactor );
                hc2  = KiROUND( hc2 * size_v * s_HersheyScaleFactor );

                // To simulate an italic font,
                // add a x offset depending on the y offset
                if( aItalic )
                    hc1 -= KiROUND( italic_reverse ? -hc2 / 8.0 : hc2 / 8.0 );

                currpoint.x = hc1 + current_char_pos.x;
                currpoint.y = hc2 + current_char_pos.y;

                RotatePoint( &currpoint, aPos, aOrient );
                coord[point_count] = currpoint;

                if( point_count < BUF_SIZE - 1 )
                    point_count++;
            }
        }    // end draw 1 char

        ptr++;

        // Apply the advance width
        current_char_pos.x += KiROUND( size_h * (xsto - xsta) * s_HersheyScaleFactor );
    }

    if( overbars % 2 )
    {
        // Close the last overbar
        coord[0]       = overbar_pos;
        overbar_pos    = current_char_pos;
        overbar_pos.y -= OverbarPositionY( size_v );
        RotatePoint( &overbar_pos, aPos, aOrient );
        coord[1] = overbar_pos;

        // Plot the overbar segment
        DrawGraphicTextPline( aClipBox, aDC, aColor, aWidth,
                              sketch_mode, 2, coord, aCallback, aPlotter );
    }
}