You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
5.4 KiB

  1. /*
  2. * This program source code file is part of KICAD, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2019-2021 Kicad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software: you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation, either version 3 of the License, or (at your
  9. * option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <preview_items/preview_utils.h>
  20. #include <gal/graphics_abstraction_layer.h>
  21. #include <base_units.h>
  22. #include <painter.h>
  23. #include <view/view.h>
  24. #include <gal/hidpi_gl_canvas.h>
  25. double KIGFX::PREVIEW::PreviewOverlayDeemphAlpha( bool aDeemph )
  26. {
  27. return aDeemph ? 0.5 : 1.0;
  28. }
  29. wxString KIGFX::PREVIEW::DimensionLabel( const wxString& prefix, double aVal, EDA_UNITS aUnits,
  30. bool aIncludeUnits )
  31. {
  32. wxString str;
  33. if( prefix.size() )
  34. str << prefix << ": ";
  35. wxString fmtStr;
  36. // show a sane precision for the preview, which doesn't need to be accurate down to the
  37. // nanometre
  38. switch( aUnits )
  39. {
  40. case EDA_UNITS::MILLIMETRES: fmtStr = wxT( "%.3f" ); break; // 1um
  41. case EDA_UNITS::MILS: fmtStr = wxT( "%.1f" ); break; // 0.1mil
  42. case EDA_UNITS::INCHES: fmtStr = wxT( "%.4f" ); break; // 0.1mil
  43. case EDA_UNITS::DEGREES: fmtStr = wxT( "%.1f" ); break; // 0.1deg
  44. case EDA_UNITS::PERCENT: fmtStr = wxT( "%.1f" ); break; // 0.1%
  45. case EDA_UNITS::UNSCALED: fmtStr = wxT( "%f" ); break;
  46. }
  47. str << wxString::Format( fmtStr, To_User_Unit( aUnits, aVal ) );
  48. if( aIncludeUnits )
  49. str << GetAbbreviatedUnitsLabel( aUnits );
  50. return str;
  51. }
  52. KIGFX::PREVIEW::TEXT_DIMS KIGFX::PREVIEW::GetConstantGlyphHeight( KIGFX::GAL* aGal,
  53. int aRelativeSize )
  54. {
  55. constexpr double aspectRatio = 1.0;
  56. constexpr double hdpiSizes[] = { 8, 9, 11, 13, 15 };
  57. constexpr double sizes[] = { 10, 12, 14, 16, 18 };
  58. double height;
  59. double thicknessFactor;
  60. double shadowFactor;
  61. double linePitchFactor;
  62. HIDPI_GL_CANVAS* canvas = dynamic_cast<HIDPI_GL_CANVAS*>( aGal );
  63. if( canvas && canvas->GetScaleFactor() > 1 )
  64. {
  65. height = hdpiSizes[ 2 + aRelativeSize ];
  66. thicknessFactor = 0.15;
  67. shadowFactor = 0.10;
  68. linePitchFactor = 1.7;
  69. }
  70. else
  71. {
  72. height = sizes[ 2 + aRelativeSize ];
  73. thicknessFactor = 0.20;
  74. shadowFactor = 0.15;
  75. linePitchFactor = 1.9;
  76. }
  77. height /= aGal->GetWorldScale();
  78. TEXT_DIMS textDims;
  79. textDims.GlyphSize = VECTOR2I( height * aspectRatio, height );
  80. textDims.StrokeWidth = height * thicknessFactor;
  81. textDims.ShadowWidth = height * shadowFactor;
  82. textDims.LinePitch = height * linePitchFactor;
  83. return textDims;
  84. }
  85. KIGFX::COLOR4D KIGFX::PREVIEW::GetShadowColor( const KIGFX::COLOR4D& aColor )
  86. {
  87. if( aColor.GetBrightness() > 0.5 )
  88. return COLOR4D::BLACK;
  89. else
  90. return COLOR4D::WHITE;
  91. }
  92. void KIGFX::PREVIEW::DrawTextNextToCursor( KIGFX::VIEW* aView, const VECTOR2D& aCursorPos,
  93. const VECTOR2D& aTextQuadrant,
  94. const std::vector<wxString>& aStrings,
  95. bool aDrawingDropShadows )
  96. {
  97. KIGFX::GAL* gal = aView->GetGAL();
  98. KIFONT::FONT* font = KIFONT::FONT::GetFont();
  99. // constant text size on screen
  100. TEXT_DIMS textDims = GetConstantGlyphHeight( gal );
  101. TEXT_ATTRIBUTES textAttrs;
  102. // radius string goes on the right of the cursor centre line with a small horizontal
  103. // offset (enough to keep clear of a system cursor if present)
  104. VECTOR2D textPos = aCursorPos;
  105. bool viewFlipped = gal->IsFlippedX();
  106. // if the text goes above the cursor, shift it up
  107. if( aTextQuadrant.y > 0 )
  108. textPos.y -= textDims.LinePitch * ( aStrings.size() + 1 );
  109. if( aTextQuadrant.x < 0 )
  110. {
  111. if( viewFlipped )
  112. textAttrs.m_Halign = GR_TEXT_H_ALIGN_RIGHT;
  113. else
  114. textAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
  115. textPos.x += 15.0 / gal->GetWorldScale();
  116. }
  117. else
  118. {
  119. if( viewFlipped )
  120. textAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
  121. else
  122. textAttrs.m_Halign = GR_TEXT_H_ALIGN_RIGHT;
  123. textPos.x -= 15.0 / gal->GetWorldScale();
  124. }
  125. gal->SetStrokeColor( aView->GetPainter()->GetSettings()->GetLayerColor( LAYER_AUX_ITEMS ) );
  126. textAttrs.m_Mirrored = viewFlipped; // Prevent text flipping when view is flipped
  127. textAttrs.m_Size = textDims.GlyphSize;
  128. textAttrs.m_StrokeWidth = textDims.StrokeWidth;
  129. if( aDrawingDropShadows )
  130. {
  131. textAttrs.m_StrokeWidth = textDims.StrokeWidth + ( 2 * textDims.ShadowWidth );
  132. gal->SetStrokeColor( GetShadowColor( gal->GetStrokeColor() ) );
  133. }
  134. // write strings top-to-bottom
  135. for( const wxString& str : aStrings )
  136. {
  137. textPos.y += textDims.LinePitch;
  138. font->Draw( gal, str, textPos, textAttrs );
  139. }
  140. }