• QT源码拾贝0-5(qimage和qpainter)


    目录

    0   qt源码查看方法

    1.  qimage.cpp中线程池使用方法

    2.  qpainter_p.h中SmallStack模板元结构体存放智能指针

    3.  qpainter.cpp的保存函数,状态对象赋值使用std::exchange函数

    4.  qpainter.cpp中获得类对象的方法

    5.  qpainter.cpp中QChar字节操作,使用u在字节前面



    0   qt源码查看方法

    使用vscode工具,加载qt源码路径,比如:C:\Qt\6.5.0\Src

    再安装一个C/C++插件:

    按住ctrl+鼠标,可以方便查看引用函数的定义。

    返回上次光标位置,使用快捷键Alt和方向左/右键

    跳过单个变量,使用快捷键ctrl加方向左/右键

    1.  qimage.cpp中线程池使用方法

    1. /*!
    2. \since 5.14
    3. Applies the color transformation \a transform to all pixels in the image.
    4. */
    5. void QImage::applyColorTransform(const QColorTransform &transform)
    6. {
    7. if (transform.isIdentity())
    8. return;
    9. detach();
    10. if (!d)
    11. return;
    12. if (pixelFormat().colorModel() == QPixelFormat::Indexed) {
    13. for (int i = 0; i < d->colortable.size(); ++i)
    14. d->colortable[i] = transform.map(d->colortable[i]);
    15. return;
    16. }
    17. QImage::Format oldFormat = format();
    18. if (qt_fpColorPrecision(oldFormat)) {
    19. if (oldFormat != QImage::Format_RGBX32FPx4 && oldFormat != QImage::Format_RGBA32FPx4
    20. && oldFormat != QImage::Format_RGBA32FPx4_Premultiplied)
    21. convertTo(QImage::Format_RGBA32FPx4);
    22. } else if (depth() > 32) {
    23. if (oldFormat != QImage::Format_RGBX64 && oldFormat != QImage::Format_RGBA64
    24. && oldFormat != QImage::Format_RGBA64_Premultiplied)
    25. convertTo(QImage::Format_RGBA64);
    26. } else if (oldFormat != QImage::Format_ARGB32 && oldFormat != QImage::Format_RGB32
    27. && oldFormat != QImage::Format_ARGB32_Premultiplied) {
    28. if (hasAlphaChannel())
    29. convertTo(QImage::Format_ARGB32);
    30. else
    31. convertTo(QImage::Format_RGB32);
    32. }
    33. QColorTransformPrivate::TransformFlags flags = QColorTransformPrivate::Unpremultiplied;
    34. switch (format()) {
    35. case Format_ARGB32_Premultiplied:
    36. case Format_RGBA64_Premultiplied:
    37. case Format_RGBA32FPx4_Premultiplied:
    38. flags = QColorTransformPrivate::Premultiplied;
    39. break;
    40. case Format_RGB32:
    41. case Format_RGBX64:
    42. case Format_RGBX32FPx4:
    43. flags = QColorTransformPrivate::InputOpaque;
    44. break;
    45. case Format_ARGB32:
    46. case Format_RGBA64:
    47. case Format_RGBA32FPx4:
    48. break;
    49. default:
    50. Q_UNREACHABLE();
    51. }
    52. std::function<void(int,int)> transformSegment;
    53. if (qt_fpColorPrecision(format())) {
    54. transformSegment = [&](int yStart, int yEnd) {
    55. for (int y = yStart; y < yEnd; ++y) {
    56. QRgbaFloat32 *scanline = reinterpret_cast(d->data + y * d->bytes_per_line);
    57. QColorTransformPrivate::get(transform)->apply(scanline, scanline, width(), flags);
    58. }
    59. };
    60. } else if (depth() > 32) {
    61. transformSegment = [&](int yStart, int yEnd) {
    62. for (int y = yStart; y < yEnd; ++y) {
    63. QRgba64 *scanline = reinterpret_cast(d->data + y * d->bytes_per_line);
    64. QColorTransformPrivate::get(transform)->apply(scanline, scanline, width(), flags);
    65. }
    66. };
    67. } else {
    68. transformSegment = [&](int yStart, int yEnd) {
    69. for (int y = yStart; y < yEnd; ++y) {
    70. QRgb *scanline = reinterpret_cast(d->data + y * d->bytes_per_line);
    71. QColorTransformPrivate::get(transform)->apply(scanline, scanline, width(), flags);
    72. }
    73. };
    74. }
    75. #if QT_CONFIG(thread) && !defined(Q_OS_WASM)
    76. int segments = (qsizetype(width()) * height()) >> 16;
    77. segments = std::min(segments, height());
    78. QThreadPool *threadPool = QThreadPool::globalInstance();
    79. if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
    80. QSemaphore semaphore;
    81. int y = 0;
    82. for (int i = 0; i < segments; ++i) {
    83. int yn = (height() - y) / (segments - i);
    84. threadPool->start([&, y, yn]() {
    85. transformSegment(y, y + yn);
    86. semaphore.release(1);
    87. });
    88. y += yn;
    89. }
    90. semaphore.acquire(segments);
    91. } else
    92. #endif
    93. transformSegment(0, height());
    94. if (oldFormat != format())
    95. *this = std::move(*this).convertToFormat(oldFormat);
    96. }

    2.  qpainter_p.h中SmallStack模板元结构体存放智能指针

    1. std::unique_ptr state;
    2. template <typename T, std::size_t N = 8>
    3. struct SmallStack : std::stack> {
    4. void clear() { this->c.clear(); }
    5. };
    6. SmallStack> savedStates;
    7. mutable std::unique_ptr dummyState;

    3.  qpainter.cpp的保存函数,状态对象赋值使用std::exchange函数

    1. void QPainter::save()
    2. {
    3. #ifdef QT_DEBUG_DRAW
    4. if (qt_show_painter_debug_output)
    5. printf("QPainter::save()\n");
    6. #endif
    7. Q_D(QPainter);
    8. if (!d->engine) {
    9. qWarning("QPainter::save: Painter not active");
    10. return;
    11. }
    12. std::unique_ptr prev;
    13. if (d->extended) {
    14. // separate the creation of a new state from the update of d->state, since some
    15. // engines access d->state directly (not via createState()'s argument)
    16. std::unique_ptr next(d->extended->createState(d->state.get()));
    17. prev = std::exchange(d->state, std::move(next));
    18. d->extended->setState(d->state.get());
    19. } else {
    20. d->updateState(d->state);
    21. prev = std::exchange(d->state, std::make_unique(d->state.get()));
    22. d->engine->state = d->state.get();
    23. }
    24. d->savedStates.push(std::move(prev));
    25. }

    4.  qpainter.cpp中获得类对象的方法

    1. QBrush QPaintEngineState::brush() const
    2. {
    3. return static_cast<const QPainterState *>(this)->brush;
    4. }

    5.  qpainter.cpp中QChar字节操作,使用u在字节前面

    1. int old_offset = offset;
    2. for (; offset < text.size(); offset++) {
    3. QChar chr = text.at(offset);
    4. if (chr == u'\r' || (singleline && chr == u'\n')) {
    5. text[offset] = u' ';
    6. } else if (chr == u'\n') {
    7. text[offset] = QChar::LineSeparator;
    8. } else if (chr == u'&') {
    9. ++maxUnderlines;
    10. } else if (chr == u'\t') {
    11. if (!expandtabs) {
    12. text[offset] = u' ';
    13. } else if (!tabarraylen && !tabstops) {
    14. tabstops = qRound(fm.horizontalAdvance(u'x')*8);
    15. }
    16. } else if (chr == u'\x9c') {
    17. // string with multiple length variants
    18. hasMoreLengthVariants = true;
    19. break;
    20. }
    21. }
    22. QList underlineFormats;
    23. int length = offset - old_offset;
    24. if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) {
    25. QChar *cout = text.data() + old_offset;
    26. QChar *cout0 = cout;
    27. QChar *cin = cout;
    28. int l = length;
    29. while (l) {
    30. if (*cin == u'&') {
    31. ++cin;
    32. --length;
    33. --l;
    34. if (!l)
    35. break;
    36. if (*cin != u'&' && !hidemnmemonic && !(tf & Qt::TextDontPrint)) {
    37. QTextLayout::FormatRange range;
    38. range.start = cout - cout0;
    39. range.length = 1;
    40. range.format.setFontUnderline(true);
    41. underlineFormats.append(range);
    42. }
    43. #ifdef Q_OS_MAC
    44. } else if (hidemnmemonic && *cin == u'(' && l >= 4 &&
    45. cin[1] == u'&' && cin[2] != u'&' &&
    46. cin[3] == u')') {
    47. int n = 0;
    48. while ((cout - n) > cout0 && (cout - n - 1)->isSpace())
    49. ++n;
    50. cout -= n;
    51. cin += 4;
    52. length -= n + 4;
    53. l -= 4;
    54. continue;
    55. #endif //Q_OS_MAC
    56. }
    57. *cout = *cin;
    58. ++cout;
    59. ++cin;
    60. --l;
    61. }
    62. }

  • 相关阅读:
    JWT简介& JWT结构& JWT示例& 前端添加JWT令牌功能& 后端程序
    搭建内部知识库,解决企业内部琐碎信息问题
    java计算机毕业设计springboot+vue网上购物商城系统
    Linux IP地址、主机名
    在EF Core中为数据表按列加密存储
    react+ts之router管理
    迁徙数据平台简单介绍
    【Arduino+ESP32专题】串口的简单使用
    LeetCode每日一练 —— 88. 合并两个有序数组
    Spring 事务传播机制源码浅析——PROPAGATION_REQUIRES_NEW
  • 原文地址:https://blog.csdn.net/yantuguiguziPGJ/article/details/127942628