Merge remote-tracking branch 'origin/GP-1512-dragonmacher-screenshot-fix'

This commit is contained in:
Ryan Kurtz 2021-11-23 13:57:28 -05:00
commit 2fb860bcd7
3 changed files with 49 additions and 45 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Before After
Before After

View file

@ -15,7 +15,7 @@
*/
package help.screenshot;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.*;
import java.awt.*;
import java.awt.geom.GeneralPath;
@ -286,8 +286,8 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
/**
* The same as {@link GhidraScreenShotGenerator#captureIsolatedProvider(Class, int, int)}
* except this method will also capture the containing window.
*
* @param clazz the provider class
*
* @param clazz the provider class
* @param width the width of the capture
* @param height the height of the capture
*/
@ -464,10 +464,10 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
}
/**
* Captures the provider by using a screen shot and not by painting the provider directly
* Captures the provider by using a screen shot and not by painting the provider directly
* (as does {@link #captureProvider(ComponentProvider)}). Use this method if you need to
* capture the provider along with any popup windows.
*
*
* @param provider the provider
*/
public void captureProviderWithScreenShot(ComponentProvider provider) {
@ -487,14 +487,14 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
}
/**
* Captures the window, including decorations. This will use a {@link Robot} to create a
* Captures the window, including decorations. This will use a {@link Robot} to create a
* screen capture, which has the effect of getting all items within the window bounds. This
* method is needed if you wish to capture child windows, like popups/hovers.
*
* <P>Other capture methods will not use the screen capture mechanism, but rather will
* directly render the given component. In this case, subordinate windows will not be
*
* <P>Other capture methods will not use the screen capture mechanism, but rather will
* directly render the given component. In this case, subordinate windows will not be
* captured. For example, see {@link #captureProvider(Class)}.
*
*
* @param name the provider's name
*/
public void captureProviderWindow(String name) {
@ -504,14 +504,14 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
}
/**
* Captures the window, including decorations. This will use a {@link Robot} to create a
* Captures the window, including decorations. This will use a {@link Robot} to create a
* screen capture, which has the effect of getting all items within the window bounds. This
* method is needed if you wish to capture child windows, like popups/hovers.
*
* <P>Other capture methods will not use the screen capture mechanism, but rather will
* directly render the given component. In this case, subordinate windows will not be
*
* <P>Other capture methods will not use the screen capture mechanism, but rather will
* directly render the given component. In this case, subordinate windows will not be
* captured. For example, see {@link #captureProvider(Class)}.
*
*
* @param clazz the provider's class
*/
public void captureProviderWindow(Class<? extends ComponentProvider> clazz) {
@ -520,14 +520,14 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
}
/**
* Captures the window, including decorations. This will use a {@link Robot} to create a
* Captures the window, including decorations. This will use a {@link Robot} to create a
* screen capture, which has the effect of getting all items within the window bounds. This
* method is needed if you wish to capture child windows, like popups/hovers.
*
* <P>Other capture methods will not use the screen capture mechanism, but rather will
* directly render the given component. In this case, subordinate windows will not be
*
* <P>Other capture methods will not use the screen capture mechanism, but rather will
* directly render the given component. In this case, subordinate windows will not be
* captured. For example, see {@link #captureProvider(Class)}.
*
*
* @param provider the provider
*/
public void captureProviderWindow(ComponentProvider provider) {
@ -536,14 +536,14 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
}
/**
* Captures the window, including decorations. This will use a {@link Robot} to create a
* Captures the window, including decorations. This will use a {@link Robot} to create a
* screen capture, which has the effect of getting all items within the window bounds. This
* method is needed if you wish to capture child windows, like popups/hovers.
*
* <P>Other capture methods will not use the screen capture mechanism, but rather will
* directly render the given component. In this case, subordinate windows will not be
*
* <P>Other capture methods will not use the screen capture mechanism, but rather will
* directly render the given component. In this case, subordinate windows will not be
* captured. For example, see {@link #captureProvider(Class)}.
*
*
* @param name the provider's name
* @param width the desired width
* @param height the desired height
@ -557,14 +557,14 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
}
/**
* Captures the window, including decorations. This will use a {@link Robot} to create a
* Captures the window, including decorations. This will use a {@link Robot} to create a
* screen capture, which has the effect of getting all items within the window bounds. This
* method is needed if you wish to capture child windows, like popups/hovers.
*
* <P>Other capture methods will not use the screen capture mechanism, but rather will
* directly render the given component. In this case, subordinate windows will not be
*
* <P>Other capture methods will not use the screen capture mechanism, but rather will
* directly render the given component. In this case, subordinate windows will not be
* captured. For example, see {@link #captureProvider(Class)}.
*
*
* @param provider the provider's name
* @param width the desired width
* @param height the desired height
@ -607,7 +607,7 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
// The image returned here must be a BufferedImage, so create one
// if not. It may be a ToolkitImage (eg: if the icon in question
// is retrieved from Icons.java), which would fail on a cast to
// is retrieved from Icons.java), which would fail on a cast to
// BufferedImage during the save operation.
image = ImageUtils.getBufferedImage(image);
});
@ -763,7 +763,7 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
public void generateImage(Component c) {
// Note: using the screen image has the downside of capturing non-Ghidra windows when
// Note: using the screen image has the downside of capturing non-Ghidra windows when
// focus is lost. Prefer the component painting itself. This will not work
// for native constructs like window decorations.
if (!(c instanceof Window)) {
@ -1275,13 +1275,16 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
}
public void positionListingTop(final long address) {
runSwing(() -> {
public void positionListingTop(long address) {
boolean didGoTo = runSwing(() -> {
CodeBrowserPlugin plugin = getPlugin(tool, CodeBrowserPlugin.class);
FieldPanel fieldPanel = plugin.getFieldPanel();
plugin.goToField(addr(address), AddressFieldFactory.FIELD_NAME, 0, 0);
boolean result = plugin.goToField(addr(address), AddressFieldFactory.FIELD_NAME, 0, 0);
fieldPanel.positionCursor(0);
return result;
});
assertTrue("Go To failed for address: " + address, didGoTo);
}
public void positionListingCenter(final long address) {
@ -1386,16 +1389,16 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
* Draws a rectangle around the given component. The root parameter is used to calculate
* screen coordinates. This allows you to capture a sub-component of a UI, drawing
* rectangles around children of said sub-component.
*
* <P>If you are unsure of what to pass for <code>root</code>, the call
*
* <P>If you are unsure of what to pass for <code>root</code>, the call
* {@link #drawRectangleAround(JComponent, Color, int)} instead.
*
*
* @param component the component to be en-rectangled
* @param root the outermost container widget being displayed; null implies a
* @param root the outermost container widget being displayed; null implies a
* top-level parent
* @param color the rectangle color
* @param padding the space between the rectangle and the component; more space makes
* the component more visible
* the component more visible
* @return the bounds of the drawn rectangle
*/
public Rectangle drawRectangleAround(JComponent component, JComponent root, Color color,
@ -1583,9 +1586,9 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
/**
* Crops a part of the current image, keeping what is inside the given bounds. This method
* creates a shape such that the top and bottom of the cropped image have a jagged line,
* creates a shape such that the top and bottom of the cropped image have a jagged line,
* looking somewhat like a sideways lightening bolt.
*
*
* @param bounds the bounds to keep
* @return the snippet
*/

View file

@ -144,15 +144,16 @@ public class CodeBrowserPluginScreenShots extends GhidraScreenShotGenerator {
@Test
public void testCaptureSelectionTable() {
setToolSize(1100, 700);
positionListingTop(0x0406bd7);
makeSelection(0x0406be1, 0x0406bf1);
positionListingTop(0x0406bd5);
makeSelection(0x0406be1, 0x0406bf6);
performAction("Create Table From Selection", "CodeBrowserSelectionPlugin", true);
Window window = waitForWindowByTitleContaining("Selection Table");
Point loc = plugin.getListingPanel().getLocationOnScreen();
Dimension size = window.getSize();
window.setBounds(loc.x + 300, loc.y + 150, size.width, 300);
captureProvider(CodeViewerProvider.class);
CodeViewerProvider provider = getProvider(CodeViewerProvider.class);
captureProviderWithScreenShot(provider);
}
@Test