Measurement.cpp
1 #include "pch.h" 2 3 #include "Measurement.h" 4 5 #include <iostream> 6 7 Measurement::Measurement(RECT winRect, float px2mmRatio) : 8 px2mmRatio{ px2mmRatio } 9 { 10 rect.left = static_cast<float>(winRect.left); 11 rect.right = static_cast<float>(winRect.right); 12 rect.top = static_cast<float>(winRect.top); 13 rect.bottom = static_cast<float>(winRect.bottom); 14 } 15 16 Measurement::Measurement(D2D1_RECT_F d2dRect, float px2mmRatio) : 17 rect{ d2dRect }, px2mmRatio{ px2mmRatio } 18 { 19 } 20 21 namespace 22 { 23 inline float Convert(const float pixels, const Measurement::Unit units, float px2mmRatio) 24 { 25 if (px2mmRatio > 0) 26 { 27 switch (units) 28 { 29 case Measurement::Unit::Pixel: 30 return pixels; 31 case Measurement::Unit::Inch: 32 return pixels * px2mmRatio / 10.0f / 2.54f; 33 case Measurement::Unit::Centimetre: 34 return pixels * px2mmRatio / 10.0f; 35 case Measurement::Unit::Millimetre: 36 return pixels * px2mmRatio; 37 default: 38 return pixels; 39 } 40 } 41 else 42 { 43 switch (units) 44 { 45 case Measurement::Unit::Pixel: 46 return pixels; 47 case Measurement::Unit::Inch: 48 return pixels / 96.0f; 49 case Measurement::Unit::Centimetre: 50 return pixels / 96.0f * 2.54f; 51 case Measurement::Unit::Millimetre: 52 return pixels / 96.0f / 10.0f * 2.54f; 53 default: 54 return pixels; 55 } 56 } 57 } 58 } 59 60 winrt::hstring Measurement::abbreviations[4]{}; 61 62 inline float Measurement::Width(const Unit units) const 63 { 64 return Convert(rect.right - rect.left + 1.f, units, px2mmRatio); 65 } 66 67 inline float Measurement::Height(const Unit units) const 68 { 69 return Convert(rect.bottom - rect.top + 1.f, units, px2mmRatio); 70 } 71 72 Measurement::Unit Measurement::GetUnitFromIndex(int index) 73 { 74 switch (index) 75 { 76 case 0: 77 return Measurement::Unit::Pixel; 78 case 1: 79 return Measurement::Unit::Inch; 80 case 2: 81 return Measurement::Unit::Centimetre; 82 case 3: 83 return Measurement::Unit::Millimetre; 84 default: 85 return Measurement::Unit::Pixel; 86 } 87 } 88 89 void Measurement::InitResources() 90 { 91 auto rm = winrt::ResourceManager{}; 92 auto mm = rm.MainResourceMap(); 93 abbreviations[0] = mm.GetValue(L"Resources/MeasurementUnitAbbrPixel").ValueAsString(); 94 abbreviations[1] = mm.GetValue(L"Resources/MeasurementUnitAbbrInch").ValueAsString(); 95 abbreviations[2] = mm.GetValue(L"Resources/MeasurementUnitAbbrCentimetre").ValueAsString(); 96 abbreviations[3] = mm.GetValue(L"Resources/MeasurementUnitAbbrMillimetre").ValueAsString(); 97 } 98 99 const wchar_t* Measurement::GetUnitAbbreviation(Measurement::Unit units) 100 { 101 switch (units) 102 { 103 case Unit::Pixel: 104 return abbreviations[0].c_str(); 105 case Unit::Inch: 106 return abbreviations[1].c_str(); 107 case Unit::Centimetre: 108 return abbreviations[2].c_str(); 109 case Unit::Millimetre: 110 return abbreviations[3].c_str(); 111 default: 112 return L"??"; 113 } 114 } 115 116 Measurement::PrintResult Measurement::Print(wchar_t* buf, 117 const size_t bufSize, 118 const bool printWidth, 119 const bool printHeight, 120 const int units) const 121 { 122 PrintResult result; 123 124 auto print = [=, &result](Measurement::Unit unit, const bool paren) { 125 if (paren) 126 { 127 result.strLen += swprintf_s(buf + result.strLen, bufSize - result.strLen, printWidth && printHeight ? L"\n(" : L" ("); 128 } 129 if (printWidth) 130 { 131 result.strLen += swprintf_s(buf + result.strLen, 132 bufSize - result.strLen, 133 L"%.4g", 134 Width(unit)); 135 if (printHeight) 136 { 137 result.crossSymbolPos[paren] = result.strLen + 1; 138 result.strLen += swprintf_s(buf + result.strLen, 139 bufSize - result.strLen, 140 L" \x00D7 "); 141 } 142 } 143 if (printHeight) 144 { 145 result.strLen += swprintf_s(buf + result.strLen, 146 bufSize - result.strLen, 147 L"%.4g", 148 Height(unit)); 149 } 150 switch (unit) 151 { 152 case Measurement::Unit::Pixel: 153 result.strLen += swprintf_s(buf + result.strLen, 154 bufSize - result.strLen, 155 L" %s", 156 Measurement::GetUnitAbbreviation(unit)); 157 break; 158 case Measurement::Unit::Inch: 159 result.strLen += swprintf_s(buf + result.strLen, 160 bufSize - result.strLen, 161 L" %s", 162 Measurement::GetUnitAbbreviation(unit)); 163 break; 164 case Measurement::Unit::Centimetre: 165 result.strLen += swprintf_s(buf + result.strLen, 166 bufSize - result.strLen, 167 L" %s", 168 Measurement::GetUnitAbbreviation(unit)); 169 170 break; 171 case Measurement::Unit::Millimetre: 172 result.strLen += swprintf_s(buf + result.strLen, 173 bufSize - result.strLen, 174 L" %s", 175 Measurement::GetUnitAbbreviation(unit)); 176 177 break; 178 } 179 if (paren) 180 { 181 result.strLen += swprintf_s(buf + result.strLen, bufSize - result.strLen, L")"); 182 } 183 }; 184 185 int count = 0; 186 const Measurement::Unit allUnits[] = { 187 Measurement::Unit::Pixel, 188 Measurement::Unit::Millimetre, 189 Measurement::Unit::Inch, 190 Measurement::Unit::Centimetre, 191 }; 192 // We only use two units at most, it would be to long otherwise. 193 for each (Measurement::Unit unit in allUnits) 194 { 195 if ((unit & units) == unit) 196 { 197 count += 1; 198 if (count > 2) 199 break; 200 print(unit, count != 1); 201 } 202 } 203 204 return result; 205 } 206 207 void Measurement::PrintToStream(std::wostream& stream, 208 const bool prependNewLine, 209 const bool printWidth, 210 const bool printHeight, 211 const Unit units) const 212 { 213 if (prependNewLine) 214 { 215 stream << std::endl; 216 } 217 218 if (printWidth) 219 { 220 stream << Width(units); 221 if (printHeight) 222 { 223 stream << L" \x00D7 "; 224 } 225 } 226 227 if (printHeight) 228 { 229 stream << Height(units); 230 } 231 232 // If the unit is pixels, then the abbreviation will not be saved as it used to be. 233 if (units != Measurement::Unit::Pixel) 234 { 235 stream << L" " << Measurement::GetUnitAbbreviation(units); 236 } 237 }