Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 325c6ab4 authored by Boudewijn Rempt's avatar Boudewijn Rempt

* Fix Thomas' popup niggles

* Place the dockers in the right order
* Experiment some more with the dcop interface
* Update todo & remove implemented stu8ff from the colorstrategyAPI document.

svn path=/trunk/koffice/; revision=444209
parent dd75c9d5
......@@ -19,7 +19,13 @@ Transform tool (CBR)
* Fix problem of deselecting during tool use
* Fix problem of undoing during tool use
* Fix problem of clearing "extraLength pixels"
* Add a messagebox that asks whether the changes should be committed or not:
"Sure you want to cancel the Transform" ?
[Discard] [Apply] [Cancel]
* Apply the changes first on the canvas pixmap, not on the actual layer for
quick interactivity
Integration
......@@ -38,8 +44,6 @@ Integration
Colorspace independence (found with the test colorstrategy)
TOMORROW
* tool gradient uses wrong colors
* brightness/contrast and the like don't work.
* Map colorspace transforms using the full set of discriminating features:
......@@ -94,6 +98,8 @@ Import/Export
User Interface
* Add opacity widget (One that grows more white or transparent (showing those gray blocks) based on the
input)
* Add out-of-gamut selection
* Fix crash with tablet because of tool refactoring.
* Fix layout problems in tool option widgets.
......@@ -119,7 +125,6 @@ User Interface
move the crop rectangle by dragging in the middle, when pressing shift, keep aspect ratio, implement
gray mask. (Michael Thaler)
* Allow shape tools to be filled with gradients
Dockers
* Tabs in dockers drag-and-droppable (vector of docker
windows, create new docker if tab dropped outside existing
......@@ -139,7 +144,11 @@ User Interface
it onto a background image -- or not, if another KOffice app wants it
rendered with transparency. But that'd probably better wait until Qt 4,
where it would be a hardware accelerated snip.
* Put rotateimage, not rotatelayer in the toolbar
* In the Layers popup-menu the 'level' talks about formost and hindmost,
since the dialog is about stacking vertically instead of horizontally, I'd use 'top
most' and 'bottom most'
Selections
......@@ -163,7 +172,7 @@ Profiles
Tools
* All tools must have a tool options tab (#Boudewijn, Adrian, Cyrille)
* Zoom tool should zoom out when alt is pressed. Show zoom-minus cursor in that case
* Implement the following tools or paintops:
- fix airbrush tool (add rate option, add increase
of brush size if kept in one place)
......@@ -181,7 +190,7 @@ Tools
* Implement path tools (Michael Thaler?)
* Sumi-e brush tool
* Natural media tools (chalk, ink, oil, watercolour -- fun!)
* Add statusbar messages for tools about modifier keys and other use hints
Plugins
......
......@@ -282,7 +282,7 @@ public:
/**
* Apply the adjustment created with on of the other functions
* Apply the adjustment created with onr of the other functions
*/
virtual void applyAdjustment(const Q_UINT8 *src, Q_UINT8 *dst, KisColorAdjustment *, Q_INT32 nPixels);
......
......@@ -105,7 +105,7 @@ namespace krita {
const QString CONTROL_PALETTE ("controlpalette");
const QString PAINTBOX ("paintbox");
const QString COLORBOX ("colorbox");
const QString LAYERBOX ("layerbox");
}
#endif // KISGLOBAL_H_
......
......@@ -801,7 +801,7 @@ QImage KisPaintDevice::convertToQImage(KisProfileSP dstProfile, Q_INT32 x1, Q_IN
if (h < 0)
h = 0;
QUANTUM * data = new QUANTUM[w * h * m_pixelSize];
Q_UINT8 * data = new Q_UINT8 [w * h * m_pixelSize];
Q_CHECK_PTR(data);
m_datamanager -> readBytes(data, x1, y1, w, h);
......@@ -895,6 +895,7 @@ void KisPaintDevice::subtractSelection(KisSelectionSP selection) {
void KisPaintDevice::clearSelection()
{
if (!hasSelection()) return;
QRect r = m_selection -> selectedRect();
......@@ -907,10 +908,11 @@ void KisPaintDevice::clearSelection()
while (!devIt.isDone()) {
KisPixel p = toPixel(devIt.rawData());
KisPixel s = m_selection -> toPixel(selectionIt.rawData());
// XXX: Why Q_UIN16 here? Doesn't that clash with UINT8_MULT later on?
Q_UINT16 p_alpha, s_alpha;
p_alpha = p.alpha();
s_alpha = MAX_SELECTED - s.alpha();
// XXX: Move to colorspace
p.alpha() = UINT8_MULT(p_alpha, s_alpha);
++devIt;
......@@ -933,7 +935,7 @@ void KisPaintDevice::applySelectionMask(KisSelectionSP mask)
KisPixel pixel = toPixel(pixelIt.rawData());
KisPixel maskValue = mask -> toPixel(maskIt.rawData());
// XXX: Move to colorspace
pixel.alpha() = (pixel.alpha() * maskValue.alpha()) / MAX_SELECTED;
++pixelIt;
......@@ -942,7 +944,7 @@ void KisPaintDevice::applySelectionMask(KisSelectionSP mask)
}
}
bool KisPaintDevice::pixel(Q_INT32 x, Q_INT32 y, QColor *c, QUANTUM *opacity)
bool KisPaintDevice::pixel(Q_INT32 x, Q_INT32 y, QColor *c, Q_UINT8 *opacity)
{
KisHLineIteratorPixel iter = createHLineIterator(x, y, 1, false);
......@@ -974,7 +976,7 @@ KisColor KisPaintDevice::colorAt(Q_INT32 x, Q_INT32 y)
return KisColor(m_datamanager -> pixel(x - m_x, y - m_y), m_colorStrategy, m_profile);
}
bool KisPaintDevice::setPixel(Q_INT32 x, Q_INT32 y, const QColor& c, QUANTUM opacity)
bool KisPaintDevice::setPixel(Q_INT32 x, Q_INT32 y, const QColor& c, Q_UINT8 opacity)
{
KisHLineIteratorPixel iter = createHLineIterator(x, y, 1, true);
......
......@@ -34,7 +34,6 @@
#include "kis_pixel.h"
#include "kis_canvas_controller.h"
#include "kis_color.h"
#include "kis_paint_device_iface.h"
#include <koffice_export.h>
class DCOPObject;
......@@ -213,7 +212,7 @@ public:
*
* @return true if the operation was succesful.
*/
bool pixel(Q_INT32 x, Q_INT32 y, QColor *c, QUANTUM *opacity);
bool pixel(Q_INT32 x, Q_INT32 y, QColor *c, Q_UINT8 *opacity);
bool pixel(Q_INT32 x, Q_INT32 y, KisColor * kc);
/**
......@@ -227,13 +226,16 @@ public:
* to QImage, not QPixmap. This means that this is not undoable; also,
* there is no compositing with an existing value at this location.
*
* The color values will be transformed from the display profile to
* the paint device profile.
* The color values will be transformed from the display profile to
* the paint device profile.
*
* Note that this will use 8-bit values and may cause a significant
* degradation when used on 16-bit or hdr quality images.
*
* @return true if the operation was succesful
*
*/
bool setPixel(Q_INT32 x, Q_INT32 y, const QColor& c, QUANTUM opacity);
bool setPixel(Q_INT32 x, Q_INT32 y, const QColor& c, Q_UINT8 opacity);
bool setPixel(Q_INT32 x, Q_INT32 y, const KisColor& kc);
/**
......
......@@ -40,4 +40,28 @@ QString KisPaintDeviceIface::name() const
void KisPaintDeviceIface::setName(const QString& name)
{
m_parent->setName(name);
}
\ No newline at end of file
}
Q_INT32 KisPaintDeviceIface::pixelSize() const
{
return m_parent->pixelSize();
}
Q_INT32 KisPaintDeviceIface::nChannels() const
{
return m_parent->nChannels();
}
QByteArray KisPaintDeviceIface::readBytes(Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h)
{
QByteArray b (w * h * m_parent->pixelSize());
m_parent->readBytes((Q_UINT8*)b.data(), x, y, w, h);
return b;
}
void KisPaintDeviceIface::writeBytes(QByteArray bytes, Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h)
{
m_parent->writeBytes((Q_UINT8*)bytes.data(), x, y, w, h);
}
......@@ -36,6 +36,38 @@ k_dcop:
virtual QString name() const;
virtual void setName(const QString& name);
/**
* Return the number of bytes a pixel takes.
*/
Q_INT32 pixelSize() const;
/**
* Return the number of channels a pixel takes
*/
Q_INT32 nChannels() const;
/**
* Read the bytes representing the rectangle described by x, y, w, h into
* data. If data is not big enough, Krita will gladly overwrite the rest
* of your precious memory.
*
* Since this is a copy, you need to make sure you have enough memory.
*
* Reading from areas not previously initialized will read the default
* pixel value into data.
*/
QByteArray readBytes(Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h);
/**
* Copy the bytes in data into the rect specified by x, y, w, h. If there
* data is too small or uninitialized, Krita will happily read parts of
* memory you never wanted to be read.
*
* If the data is written to areas of the paint device not previously initialized,
* the paint device will grow.
*/
void writeBytes(QByteArray bytes, Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h);
private:
......
......@@ -142,6 +142,11 @@ KisView::KisView(KisDoc *doc, KisUndoAdapter *adapter, QWidget *parent, const ch
Q_CHECK_PTR(m_paletteManager);
Q_ASSERT(m_paletteManager);
m_paletteManager->createPalette( krita::CONTROL_PALETTE , i18n("Control box"));
m_paletteManager->createPalette( krita::PAINTBOX, i18n("Brushes and stuff"));
m_paletteManager->createPalette( krita::COLORBOX, i18n("Colors"));
m_paletteManager->createPalette( krita::LAYERBOX, i18n("Layers"));
m_selectionManager = new KisSelectionManager(this, doc);
Q_CHECK_PTR(m_selectionManager);
......@@ -220,7 +225,6 @@ KisView::KisView(KisDoc *doc, KisUndoAdapter *adapter, QWidget *parent, const ch
m_inputDevice = INPUT_DEVICE_MOUSE;
connect(m_doc, SIGNAL(imageListUpdated()), SLOT(docImageListUpdate()));
resetMonitorProfile();
......@@ -279,7 +283,7 @@ void KisView::createLayerBox()
connect(m_layerBox, SIGNAL(itemComposite(const KisCompositeOp&)), this, SLOT(layerCompositeOp(const KisCompositeOp&)));
connect(this, SIGNAL(currentLayerChanged(int)), m_layerBox, SLOT(slotSetCurrentItem(int)));
paletteManager()->addWidget(m_layerBox, "layerbox", "layerpalette", 0);
paletteManager()->addWidget(m_layerBox, "layerbox", krita::LAYERBOX, 0);
}
......@@ -287,7 +291,7 @@ void KisView::createPaintopBox()
{
m_paintopBox = new KisPaintopBox(this, "paintopbox");
m_paintopBox->setCaption(i18n("Brushes and stuff"));
paletteManager()->addWidget(m_paintopBox, i18n("Brushes and tools"), "paintopbox" );
paletteManager()->addWidget(m_paintopBox, i18n("Brushes and tools"), krita::PAINTBOX );
}
......
......@@ -2,84 +2,57 @@ This is a working document. It list the places where pixels are mangled and requ
The purpose is to find out which functions an API in colorstrategy must have to support pixelmangling in a colorstretegy independent manner.
====================
Requested functions:
a function that take X number of pixels and associated weights and produce a weighted average.
Requested function: apply an alpha mask to pixels
Problem: alpha is hard-coded 8-bit in KisPixel, when it should be free
void KisPaintDevice::clearSelection()
{
if (!hasSelection()) return;
QRect r = m_selection -> selectedRect();
r = r.normalize();
====================
Usecases:
for (Q_INT32 y = 0; y < r.height(); y++) {
KisHLineIterator devIt = createHLineIterator(r.x(), r.y() + y, r.width(), true);
KisHLineIterator selectionIt = m_selection -> createHLineIterator(r.x(), r.y() + y, r.width(), false);
plugins/convolutionfilters:
---------------------
The plugin creates matrices for each of the color channels. That would
be wrong. A single matrix would be enough telling how to mix the colors.
Another matrix telling how to mix the alpha is ok though.
while (!devIt.isDone()) {
KisPixel p = toPixel(devIt.rawData());
KisPixel s = m_selection -> toPixel(selectionIt.rawData());
// XXX: Why Q_UIN16 here? Doesn't that clash with UINT8_MULT later on?
Q_UINT16 p_alpha, s_alpha;
p_alpha = p.alpha();
s_alpha = MAX_SELECTED - s.alpha();
core/kis_convolution_painter.cc:
---------------------
The convolution painter assume that we know how to mix several colors into one. That won't hold for hsv and lab, and is slightly inaccurate for the other colorstrategies as well.
p.alpha() = UINT8_MULT(p_alpha, s_alpha);
core/builder/kis_image_magick_builder.cc:
---------------------
(this file will be moved to a plugin soon)
The builder is hardcoded to rgba because it needs to convert between ImageMagick
pixel packets and Krita pixels. Currently the code is like:
KisHLineIteratorPixel hiter = layer -> createHLineIterator(0, y, image->columns, true);
while(! hiter.isDone())
{
Q_UINT8 *ptr= hiter.rawData();
// XXX: not colorstrategy and bitdepth independent
*(ptr++) = pp->blue;
*(ptr++) = pp->green;
*(ptr++) = pp->red;
*(ptr++) = OPACITY_OPAQUE - pp->opacity;
pp++;
hiter++;
++devIt;
++selectionIt;
}
}
}
The traditional way of solving in Krita would be to add a toImageMagickImage
and fromImageMagick method analogous to the toQImage and fromQImage methods,
or to add nativeColor and toPixelPacket methods -- but this is not extensible,
for instance when we want to support openExr.
====================
Requested function:
void KisPaintDevice::applySelectionMask(KisSelectionSP mask)
{
QRect r = mask -> extent();
crop(r);
a function that take 2 colours, and calculates the 'distance' or 'difference' between it.
for (Q_INT32 y = r.top(); y <= r.bottom(); ++y) {
KisHLineIterator pixelIt = createHLineIterator(r.x(), y, r.width(), true);
KisHLineIterator maskIt = mask -> createHLineIterator(r.x(), y, r.width(), false);
====================
Usecases:
while (!pixelIt.isDone()) {
core/kis_fill_painter.cc:
---------------------
KisPixel pixel = toPixel(pixelIt.rawData());
KisPixel maskValue = mask -> toPixel(maskIt.rawData());
The fill painter needs to know if a pixel doesn't vary too much from the seed pixel.
Currently it calculates this in an RGB-only way, by taking the difference of the channels
of the 2 points.
pixel.alpha() = (pixel.alpha() * maskValue.alpha()) / MAX_SELECTED;
------------------------------
It is quite often necessary to blank a pixel The color strategy should have a function
to return a blank pixel. Ditto with a default pixel.
==================
Requested function
A function that takes color channels and alpha channel and combines those in the right
order and at the right place
Usecase:
KisPaintop:
++pixelIt;
++maskIt;
}
}
}
alpha from mast + color from color selector, together a new color
\ No newline at end of file
......@@ -86,6 +86,12 @@ public:
*
* If the widget occurs in the saved configuration, it is not added to the
* specified palette, but in the place where it was left.
*
* @param widget the widget that will be inserted as a tab or entry in the palette
* @param name the name under which the palette will be stored. Not the caption -- do not i18n this.
* @param paletteName the unique name of the palette this widget will be a child of. If the palette already exists, the current widget is added to it.
* @param position the position of the widget in the palettes
* @param style docker, toolbox or slider
*/
virtual void addWidget(QWidget * widget, const QString & name, const QString & paletteName, int position = -1, enumKoPaletteStyle style = PALETTE_DOCKER);
......@@ -114,7 +120,7 @@ public:
/**
* Create a palette in the given style. with the given name and caption. If
* Create an empty palette in the given style. with the given name and caption. If
* the palette already exists, nothing is done.
*/
virtual KoPalette * createPalette(const QString & name, const QString & caption, enumKoPaletteStyle style = PALETTE_DOCKER);
......
......@@ -91,7 +91,7 @@ KisControlFrame::KisControlFrame( KisView * view, QWidget* parent, const char* n
setLineWidth(1);
m_font = KGlobalSettings::generalFont();
float ps = m_font.pointSize() * 0.7;
float ps = m_font.pointSize() * 0.8;
m_font.setPointSize((int)ps);
m_toolbar = new KToolBar(m_view->mainWindow(), Qt::DockLeft, false, "resources", false, true);
......@@ -99,12 +99,15 @@ KisControlFrame::KisControlFrame( KisView * view, QWidget* parent, const char* n
m_toolbar->setName("resources");
m_brushWidget = new KisIconWidget(m_toolbar, "brushes");
m_brushWidget->setTextLabel( i18n("Brush shapes") );
m_brushWidget->show();
m_patternWidget = new KisIconWidget(m_toolbar, "patterns");
m_patternWidget->setTextLabel( i18n("Fill patterns") );
m_patternWidget->show();
m_gradientWidget = new KisIconWidget(m_toolbar, "gradients");
m_gradientWidget->setTextLabel( i18n("Gradients") );
m_gradientWidget->show();
m_brushWidget -> setFixedSize( 32, 32 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment