コード例 #1
0
ファイル: byte_view_text.cpp プロジェクト: francliu/design
void ByteViewText::paintEvent(QPaintEvent *)
{
    QPainter painter(viewport());
    painter.translate(-horizontalScrollBar()->value() * font_width_, 0);
    painter.setFont(font());

    // Pixel offset of this row
    int row_y = 0;

    // Starting byte offset
    guint offset = (guint) verticalScrollBar()->value() * row_width_;

    // Clear the area
    painter.fillRect(viewport()->rect(), palette().base());

    // Offset background
    offset_normal_fg_.setColor(ColorUtils::alphaBlend(palette().windowText(), palette().window(), 0.35));
    offset_field_fg_.setColor(ColorUtils::alphaBlend(palette().windowText(), palette().window(), 0.65));
    if (show_offset_) {
        QRect offset_rect = QRect(viewport()->rect());
        offset_rect.setWidth(offsetPixels());
        painter.fillRect(offset_rect, palette().window());
    }

    if (!tvb_) {
        return;
    }

    // Map window coordinates to byte offsets
    x_pos_to_column_.clear();
    for (guint i = 0; i < row_width_; i++) {
        int sep_width = (i / separator_interval_) * font_width_;
        if (show_hex_) {
            // Hittable pixels extend 1/2 space on either side of the hex digits
            int pixels_per_byte = (recent.gui_bytes_view == BYTES_HEX ? 3 : 9) * font_width_;
            int hex_x = offsetPixels() + margin_ + sep_width + (i * pixels_per_byte) - (font_width_ / 2);
            for (int j = 0; j <= pixels_per_byte; j++) {
                x_pos_to_column_[hex_x + j] = i;
            }
        }
        if (show_ascii_) {
            int ascii_x = offsetPixels() + hexPixels() + margin_ + sep_width + (i * font_width_);
            for (int j = 0; j <= font_width_; j++) {
                x_pos_to_column_[ascii_x + j] = i;
            }
        }
    }

    // Data rows
    int widget_height = height();
    painter.save();
    while(row_y + line_spacing_ < widget_height && offset < tvb_captured_length(tvb_)) {
        drawOffsetLine(painter, offset, row_y);
        offset += row_width_;
        row_y += line_spacing_;
    }
    painter.restore();
}
コード例 #2
0
ファイル: At5toTextAdapter.cpp プロジェクト: dulton/53_hero
void tAt5toTextAdapter::getAttributes( At5::tPointStyle &pointStyle,
                                        const At5::tShapeRec& /*shapeRec*/,
                                        const tMap2dCamera& camera, 
                                        tTextStyleAttributes& tsa,
                                        const tVector2l& /*pixelCoords*/,
                                        const bool rotateText,
                                        const bool m_DrawIcon, 
                                        const unsigned short at5Version)
{
    //initialize all local variables to safe values
    tVector2l offsetMeters(0,0);
    tVector2l textOffsetMeters(0,0);
    tVector2l offsetPixels(0,0);
    tVector2l textOffsetPixels(0,0);
    //bool dispOffsetRotate = false;

    /*  
        Treat all At5 text as halo-ed text. This is possible because the tTextRender class
        ignores transparent halos.  Per the At5 specification on page 26, background color
        must be specified for the point feature to be valid.
    */
    tsa.m_halo = true;

    /*  
        Map rotations from the camera are in radians, plus At5 rotation assumes positive 
        angles = counter-clockwise rotation.  Qt rotation is in degrees (as well as the 
        fast lookup for FloatSin and FloatCos), and works with positive angles = 
        clockwise rotation.  The angle is converted to degrees then negated.
    */
    if (rotateText)
    {
        //tsa.m_rotationDegrees = -1 * shapeRec.Rotation.m_Val;
        /*zAxisRotation = -1 * (int) RadiansToDegrees(camera.TargetRotationZ());
        tsa.m_rotationDegrees = -1 * camera.ConvertRotationAngle(
            shapeRec.Rotation.m_Val, -zAxisRotation,
            tVector2l(shapeRec.Point.m_Val * (long)shapeRec.DataRes.m_Val));*/
    }

    tsa.m_fontSize = GetFontSize( pointStyle.styleAttributes.fontSize, at5Version );

    /*
        Per page 41 of the At5 specification, rotation angles for the shapeRec are in degrees.
        Experimental results show that the rotation is positive for counter-clockwise rotation.
        Because Qt (and the TextRender library) work with positive angles = clockwise rotation,
        the angle is negated.
    */

    /*
        If the rotation is set, we must add the rotation of the map to
        the rotation of the text to get the effective rotation of the text.
    */
    if (!rotateText)
    {
        tsa.m_rotationDegrees = 0; //sanity check
    }
    
    //  Set the bold flag
    if (pointStyle.styleAttributes.bold == 1)
    {
        tsa.m_bold = true;
    }
    else
    {
        tsa.m_bold = false;
    }

    if(m_DrawIcon)
    {
        if( pointStyle.styleAttributes.defaultFlag & At5::Attribute( At5::tPointStyleAttributes::eM_ColorRGBA ) )
        {
            tsa.m_color = tAt5Utils::RGBAToColor( pointStyle.styleAttributes.colorRGBA );
        }
        else
        {
            // Get the text color from the At5 Feat Def and convert to a QColor
            tsa.m_color = tAt5Utils::At5GetColor(pointStyle.styleAttributes.color);
        }
        if( pointStyle.styleAttributes.defaultFlag & At5::Attribute( At5::tPointStyleAttributes::eM_BackgroundColorRGBA ) )
        {
            tsa.m_bkgColor = tAt5Utils::RGBAToColor( pointStyle.styleAttributes.backgroundColorRGBA );
        }
        else
        {
            // Get the background color
            tsa.m_bkgColor = tAt5Utils::At5GetColor(pointStyle.styleAttributes.backgroundColor);
        }
    }
    else
    {
        // Get the text color from the At5 Feat Def and convert to a QColor
        tsa.m_color = QColor(Qt::black);
        // Get the background color
        tsa.m_bkgColor = QColor(Qt::white);
    }

    // Figure out the alignment
    At5::tPointStyleAttributes::eAlignCode tempAlign = pointStyle.styleAttributes.align;
    if ( tempAlign & 128 )// Special case of not rotating the anchor point
    {
        tsa.m_anchorPointNoRotate = true;
        //dispOffsetRotate = false;
        assert(false);
    }
    else
    {
        tsa.m_anchorPointNoRotate = false;
        //dispOffsetRotate = true;
    }
    // Next two lines are debug
    //assert(dispOffsetRotate);
    assert(!tsa.m_anchorPointNoRotate);

    tsa.m_align = At5ToFontTextAlign(tempAlign);

    offsetPixels.x = 0;
    offsetPixels.y = 0;
    assert(!(pointStyle.styleAttributes.defaultFlag & At5::Attribute(At5::tPointStyleAttributes::eM_TextOffset) && pointStyle.styleAttributes.defaultFlag & At5::Attribute(At5::tPointStyleAttributes::eM_TextOffsetMeters)));
    if(pointStyle.styleAttributes.defaultFlag & At5::Attribute(At5::tPointStyleAttributes::eM_TextOffset))
    {
        textOffsetPixels.x = (long) pointStyle.styleAttributes.textOffset.x;
        textOffsetPixels.y = (long) pointStyle.styleAttributes.textOffset.y;
    }
    else
    {
        textOffsetPixels.x = 0;
        textOffsetPixels.y = 0;
    }

    offsetMeters.x = 0;
    offsetMeters.y = 0;
    if(pointStyle.styleAttributes.defaultFlag & At5::Attribute(At5::tPointStyleAttributes::eM_TextOffsetMeters))
    {
        textOffsetMeters = tVector2l(pointStyle.styleAttributes.textOffsetMeters.x, pointStyle.styleAttributes.textOffsetMeters.y);
        if (textOffsetMeters != tVector2l::ZERO)
        {
            //only do the math if you have to
            textOffsetMeters =  tVector2l( qRound(textOffsetMeters.x / camera.RangeMMPixelAtTarget()), qRound(textOffsetMeters.y / camera.RangeMMPixelAtTarget()) ) ;
        }
    }
    else
    {
        textOffsetMeters.x = 0;
        textOffsetMeters.y = 0;
    }

    //the text offset can only be in meters or pixels.  If both are non-zero, something went wrong
    assert(!(( (textOffsetPixels.x != 0) || (textOffsetPixels.y != 0) ) && 
        ( (textOffsetMeters.x != 0) || (textOffsetMeters.y != 0))));

    assert(offsetMeters == tVector2l::ZERO);
    assert(offsetPixels == tVector2l::ZERO);
    if ((textOffsetMeters.x == 0) && (textOffsetMeters.y == 0))
    {
        tsa.m_effectiveTextOffset = textOffsetPixels;
    }
    else if ((textOffsetMeters.x !=0) || (textOffsetMeters.y != 0))
    {
        tsa.m_effectiveTextOffset = textOffsetMeters;
    }

    if (pointStyle.styleAttributes.miscCtrl & 1)
    {
        tsa.m_rotationLimited = false;
    }
    else
    {
        tsa.m_rotationLimited = true;
    }

    return;
}
コード例 #3
0
ファイル: byte_view_text.cpp プロジェクト: francliu/design
int ByteViewText::totalPixels()
{
    return offsetPixels() + hexPixels() + asciiPixels();
}
コード例 #4
0
ファイル: byte_view_text.cpp プロジェクト: francliu/design
// Draw a line of byte view text for a given offset.
// Text with different styles are split into fragments and passed to
// flushOffsetFragment. Font character widths aren't necessarily whole
// numbers so we track our X coordinate position using using floats.
void ByteViewText::drawOffsetLine(QPainter &painter, const guint offset, const int row_y)
{
    if (!tvb_) {
        return;
    }
    guint tvb_len = tvb_captured_length(tvb_);
    guint max_pos = qMin(offset + row_width_, tvb_len);
    const guint8 *pd = tvb_get_ptr(tvb_, 0, -1);

    static const guchar hexchars[16] = {
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    QString text;
    highlight_state state = StateNormal, offset_state = StateOffsetNormal;
    qreal hex_x = offsetPixels() + margin_;
    qreal ascii_x = offsetPixels() + hexPixels() + margin_;

    // Hex
    if (show_hex_) {
        for (guint tvb_pos = offset; tvb_pos < max_pos; tvb_pos++) {
            highlight_state hex_state = StateNormal;
            bool add_space = tvb_pos != offset;

            if ((tvb_pos >= f_bound_.first && tvb_pos < f_bound_.second) || (tvb_pos >= fa_bound_.first && tvb_pos < fa_bound_.second)) {
                hex_state = StateField;
                offset_state = StateOffsetField;
            } else if (tvb_pos >= p_bound_.first && tvb_pos < p_bound_.second) {
                hex_state = StateProtocol;
            }

            if (hex_state != state) {
                if ((state == StateNormal || (state == StateProtocol && hex_state == StateField)) && add_space) {
                    add_space = false;
                    text += ' ';
                    /* insert a space every separator_interval_ bytes */
                    if ((tvb_pos % separator_interval_) == 0)
                        text += ' ';
                }
                hex_x += flushOffsetFragment(painter, hex_x, row_y, state, text);
                state = hex_state;
            }

            if (add_space) {
                text += ' ';
                /* insert a space every separator_interval_ bytes */
                if ((tvb_pos % separator_interval_) == 0)
                    text += ' ';
            }

            switch (recent.gui_bytes_view) {
            case BYTES_HEX:
                text += hexchars[(pd[tvb_pos] & 0xf0) >> 4];
                text += hexchars[pd[tvb_pos] & 0x0f];
                break;
            case BYTES_BITS:
                /* XXX, bitmask */
                for (int j = 7; j >= 0; j--)
                    text += (pd[tvb_pos] & (1 << j)) ? '1' : '0';
                break;
            }
        }
    }
    if (text.length() > 0) {
        flushOffsetFragment(painter, hex_x, row_y, state, text);
    }
    state = StateNormal;

    // ASCII
    if (show_ascii_) {
        for (guint tvb_pos = offset; tvb_pos < max_pos; tvb_pos++) {
            highlight_state ascii_state = StateNormal;
            bool add_space = tvb_pos != offset;

            if ((tvb_pos >= f_bound_.first && tvb_pos < f_bound_.second) || (tvb_pos >= fa_bound_.first && tvb_pos < fa_bound_.second)) {
                ascii_state = StateField;
                offset_state = StateOffsetField;
            } else if (tvb_pos >= p_bound_.first && tvb_pos < p_bound_.second) {
                ascii_state = StateProtocol;
            }

            if (ascii_state != state) {
                if ((state == StateNormal || (state == StateProtocol && ascii_state == StateField)) && add_space) {
                    add_space = false;
                    /* insert a space every separator_interval_ bytes */
                    if ((tvb_pos % separator_interval_) == 0)
                        text += ' ';
                }
                ascii_x += flushOffsetFragment(painter, ascii_x, row_y, state, text);
                state = ascii_state;
            }

            if (add_space) {
                /* insert a space every separator_interval_ bytes */
                if ((tvb_pos % separator_interval_) == 0)
                    text += ' ';
            }

            guchar c = (encoding_ == PACKET_CHAR_ENC_CHAR_EBCDIC) ?
                        EBCDIC_to_ASCII1(pd[tvb_pos]) :
                        pd[tvb_pos];

            text += g_ascii_isprint(c) ? c : '.';
        }
    }
    if (text.length() > 0) {
        flushOffsetFragment(painter, ascii_x, row_y, state, text);
    }

    // Offset. Must be drawn last in order for offset_state to be set.
    if (show_offset_) {
        text = QString("%1").arg(offset, offsetChars(), 16, QChar('0'));
        flushOffsetFragment(painter, margin_, row_y, offset_state, text);
    }
}
コード例 #5
0
void ByteViewText::paintEvent(QPaintEvent *)
{
    QPainter painter(viewport());
    painter.translate(-horizontalScrollBar()->value() * font_width_, 0);

    // Pixel offset of this row
    int row_y = 0;

    // Starting byte offset
    int offset = verticalScrollBar()->value() * row_width_;

    // Clear the area
    painter.fillRect(viewport()->rect(), palette().base());

    // Offset background. We want the entire height to be filled.
    if (show_offset_) {
        QRect offset_rect = QRect(viewport()->rect());
        offset_rect.setWidth(offsetPixels());
        painter.fillRect(offset_rect, palette().window());
    }

    if ( data_.isEmpty() ) {
        return;
    }

    // Data rows
    int widget_height = height();
    int leading = fontMetrics().leading();
    painter.save();

    x_pos_to_column_.clear();
    while( (int) (row_y + line_height_) < widget_height && offset < (int) data_.count()) {
        drawLine(&painter, offset, row_y);
        offset += row_width_;
        row_y += line_height_ + leading;
    }

    painter.restore();

    // We can't do this in drawLine since the next line might draw over our rect.
    if (!hover_outlines_.isEmpty()) {
        qreal pen_width = 1.0;
        QPen ho_pen;
        QColor ho_color = palette().text().color();
        ho_color.setAlphaF(0.5);
        ho_pen.setColor(ho_color);
        ho_pen.setWidthF(pen_width);
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
        if (devicePixelRatio() > 1) {
            pen_width = 0.5;
        }
#endif

        painter.save();
        painter.setPen(ho_pen);
        painter.setBrush(Qt::NoBrush);
        foreach (QRect ho_rect, hover_outlines_) {
            // These look good on retina and non-retina displays on macOS.
            // We might want to use fontMetrics numbers instead.
            ho_rect.adjust(-1, 0, -1, -1);
            painter.drawRect(ho_rect);
        }